mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-01-24 05:16:39 +02:00
Parse defaults and text sections in help.xml.
These will be required to build documentation in C.
This commit is contained in:
parent
088026e6ff
commit
1d5563288c
@ -25,7 +25,7 @@
|
||||
|
||||
<!ELEMENT option-list (option+)>
|
||||
|
||||
<!ELEMENT option (summary, text, example)>
|
||||
<!ELEMENT option (summary, text, example+)>
|
||||
<!ATTLIST option id CDATA #REQUIRED>
|
||||
<!ATTLIST option section CDATA "">
|
||||
<!ATTLIST option name CDATA #REQUIRED>
|
||||
@ -45,7 +45,7 @@
|
||||
|
||||
<!ELEMENT config-key-list (config-key+)>
|
||||
|
||||
<!ELEMENT config-key (summary, text, default?, allow?, example)>
|
||||
<!ELEMENT config-key (summary, text, default?, allow?, example+)>
|
||||
<!ATTLIST config-key id CDATA #REQUIRED>
|
||||
<!ATTLIST config-key name CDATA #REQUIRED>
|
||||
|
||||
|
@ -4,7 +4,7 @@ Parse Configuration Yaml
|
||||
#ifndef BUILD_CONFIG_PARSE_H
|
||||
#define BUILD_CONFIG_PARSE_H
|
||||
|
||||
#include "common/type/stringList.h"
|
||||
#include "storage/storage.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Command role constants
|
||||
|
@ -539,7 +539,8 @@
|
||||
<p>Map file age (in days) to a block multiplier. Files that have not been modified recently are less likely to be modified in the future, so the block size is multiplied to reduce the map size. By default, if the file is old enough it will not be stored as a block incremental.</p>
|
||||
</text>
|
||||
|
||||
<example>7=2|14=4</example>
|
||||
<example>7=2</example>
|
||||
<example>14=4</example>
|
||||
</config-key>
|
||||
|
||||
<config-key id="repo-block-checksum-size-map" name="Block Incremental Checksum Size Map">
|
||||
@ -549,7 +550,8 @@
|
||||
<p>Map block size to checksum size. Smaller checksums save space in the map but may not be able to reliably detect changes in the block.</p>
|
||||
</text>
|
||||
|
||||
<example>32KiB=7|128KiB=8</example>
|
||||
<example>32KiB=7</example>
|
||||
<example>128KiB=8</example>
|
||||
</config-key>
|
||||
|
||||
<config-key id="repo-block-size-map" name="Block Incremental Size Map">
|
||||
@ -559,7 +561,9 @@
|
||||
<p>Map file size to block size. Block size is the minimum unit that will be stored in the block incremental. Smaller sizes allow for more granular incremental backups but larger sizes mean smaller maps.</p>
|
||||
</text>
|
||||
|
||||
<example>16KiB=8KiB|128KiB=16KiB|512KiB=32KiB</example>
|
||||
<example>16KiB=8KiB</example>
|
||||
<example>128KiB=16KiB</example>
|
||||
<example>512KiB=32KiB</example>
|
||||
</config-key>
|
||||
|
||||
<config-key id="repo-block-size-super" name="Block Incremental Super Block Size">
|
||||
|
@ -31,14 +31,28 @@ bldHlpParseOption(XmlNodeList *const xmlOptList, List *const optList, const Stri
|
||||
// Add option to list
|
||||
MEM_CONTEXT_BEGIN(lstMemContext(optList))
|
||||
{
|
||||
const BldHlpOption bldHlpOption =
|
||||
BldHlpOption bldHlpOption =
|
||||
{
|
||||
.name = xmlNodeAttribute(xmlOpt, STRDEF("id")),
|
||||
.section = strDup(section),
|
||||
.title = xmlNodeAttribute(xmlOpt, STRDEF("name")),
|
||||
.summary = xmlNodeChild(xmlOpt, STRDEF("summary"), true),
|
||||
.description = xmlNodeChild(xmlOpt, STRDEF("text"), true),
|
||||
};
|
||||
|
||||
// Add examples
|
||||
const XmlNodeList *const exampleList = xmlNodeChildList(xmlOpt, STRDEF("example"));
|
||||
|
||||
if (xmlNodeLstSize(exampleList) > 0)
|
||||
{
|
||||
StringList *const exampleListBuild = strLstNew();
|
||||
|
||||
for (unsigned int exampleIdx = 0; exampleIdx < xmlNodeLstSize(exampleList); exampleIdx++)
|
||||
strLstAdd(exampleListBuild, xmlNodeContent(xmlNodeLstGet(exampleList, exampleIdx)));
|
||||
|
||||
bldHlpOption.exampleList = exampleListBuild;
|
||||
}
|
||||
|
||||
lstAdd(optList, &bldHlpOption);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
@ -109,6 +123,7 @@ bldHlpParseCommandList(XmlNode *const xml)
|
||||
const BldHlpCommand bldHlpCommand =
|
||||
{
|
||||
.name = xmlNodeAttribute(xmlCmd, STRDEF("id")),
|
||||
.title = xmlNodeAttribute(xmlCmd, STRDEF("name")),
|
||||
.summary = xmlNodeChild(xmlCmd, STRDEF("summary"), true),
|
||||
.description = xmlNodeChild(xmlCmd, STRDEF("text"), true),
|
||||
.optList = lstMove(cmdOptList, memContextCurrent()),
|
||||
@ -124,6 +139,36 @@ bldHlpParseCommandList(XmlNode *const xml)
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Build section list
|
||||
***********************************************************************************************************************************/
|
||||
static List *
|
||||
bldHlpParseSectionList(XmlNode *const xml, const bool detail)
|
||||
{
|
||||
List *const result = lstNewP(sizeof(BldHlpSection), .comparator = lstComparatorStr);
|
||||
|
||||
// Build section list
|
||||
const XmlNodeList *const xmlSectionList = xmlNodeChildList(
|
||||
xmlNodeChild(xmlNodeChild(xml, STRDEF("config"), true), STRDEF("config-section-list"), true), STRDEF("config-section"));
|
||||
|
||||
for (unsigned int sectionIdx = 0; sectionIdx < xmlNodeLstSize(xmlSectionList); sectionIdx++)
|
||||
{
|
||||
const XmlNode *const xmlSection = xmlNodeLstGet(xmlSectionList, sectionIdx);
|
||||
const BldHlpSection bldHlpSection =
|
||||
{
|
||||
.id = xmlNodeAttribute(xmlSection, STRDEF("id")),
|
||||
.name = xmlNodeAttribute(xmlSection, STRDEF("name")),
|
||||
.introduction = xmlNodeChild(xmlSection, STRDEF("text"), detail),
|
||||
};
|
||||
|
||||
lstAdd(result, &bldHlpSection);
|
||||
}
|
||||
|
||||
lstSort(result, sortOrderAsc);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Reconcile help
|
||||
***********************************************************************************************************************************/
|
||||
@ -170,7 +215,7 @@ bldHlpValidate(const BldHlp bldHlp, const BldCfg bldCfg)
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
BldHlp
|
||||
bldHlpParse(const Storage *const storageRepo, const BldCfg bldCfg)
|
||||
bldHlpParse(const Storage *const storageRepo, const BldCfg bldCfg, const bool detail)
|
||||
{
|
||||
// Initialize xml
|
||||
XmlNode *const xml = xmlDocumentRoot(
|
||||
@ -179,8 +224,17 @@ bldHlpParse(const Storage *const storageRepo, const BldCfg bldCfg)
|
||||
// Parse help
|
||||
BldHlp result =
|
||||
{
|
||||
.sctList = bldHlpParseSectionList(xml, detail),
|
||||
|
||||
.cmdTitle = xmlNodeAttribute(xmlNodeChild(xml, STRDEF("operation"), true), STRDEF("title")),
|
||||
.cmdDescription = xmlNodeContent(xmlNodeChild(xmlNodeChild(xml, STRDEF("operation"), true), STRDEF("description"), detail)),
|
||||
.cmdIntroduction = xmlNodeChild(xmlNodeChild(xml, STRDEF("operation"), true), STRDEF("text"), detail),
|
||||
.cmdList = bldHlpParseCommandList(
|
||||
xmlNodeChild(xmlNodeChild(xml, STRDEF("operation"), true), STRDEF("command-list"), true)),
|
||||
|
||||
.optTitle = xmlNodeAttribute(xmlNodeChild(xml, STRDEF("config"), true), STRDEF("title")),
|
||||
.optDescription = xmlNodeContent(xmlNodeChild(xmlNodeChild(xml, STRDEF("config"), true), STRDEF("description"), detail)),
|
||||
.optIntroduction = xmlNodeChild(xmlNodeChild(xml, STRDEF("config"), true), STRDEF("text"), detail),
|
||||
.optList = bldHlpParseOptionList(xml)
|
||||
};
|
||||
|
||||
|
@ -10,9 +10,17 @@ Parse Help Xml
|
||||
/***********************************************************************************************************************************
|
||||
Types
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct BldHlpSection
|
||||
{
|
||||
const String *id; // Id
|
||||
const String *name; // Name
|
||||
const XmlNode *introduction; // Introduction
|
||||
} BldHlpSection;
|
||||
|
||||
typedef struct BldHlpCommand
|
||||
{
|
||||
const String *name; // Name
|
||||
const String *title; // Title
|
||||
const XmlNode *summary; // Summary
|
||||
const XmlNode *description; // Description
|
||||
const List *optList; // Option list
|
||||
@ -22,13 +30,24 @@ typedef struct BldHlpOption
|
||||
{
|
||||
const String *name; // Name
|
||||
const String *section; // Section
|
||||
const String *title; // Title
|
||||
const XmlNode *summary; // Summary
|
||||
const XmlNode *description; // Description
|
||||
const StringList *exampleList; // Examples
|
||||
} BldHlpOption;
|
||||
|
||||
typedef struct BldHlp
|
||||
{
|
||||
const List *sctList; // Section list
|
||||
|
||||
const String *cmdTitle; // Command title
|
||||
const String *cmdDescription; // Command description
|
||||
const XmlNode *cmdIntroduction; // Command introduction
|
||||
const List *cmdList; // Command list
|
||||
|
||||
const String *optTitle; // Option title
|
||||
const String *optDescription; // Option description
|
||||
const XmlNode *optIntroduction; // Option introduction
|
||||
const List *optList; // Option list
|
||||
} BldHlp;
|
||||
|
||||
@ -36,6 +55,6 @@ typedef struct BldHlp
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// Parse help.xml
|
||||
BldHlp bldHlpParse(const Storage *const storageRepo, const BldCfg bldCfg);
|
||||
BldHlp bldHlpParse(const Storage *const storageRepo, const BldCfg bldCfg, bool detail);
|
||||
|
||||
#endif
|
||||
|
@ -86,7 +86,7 @@ main(const int argListSize, const char *const argList[])
|
||||
if (strEqZ(STRDEF("help"), argList[1]))
|
||||
{
|
||||
const BldCfg bldCfg = bldCfgParse(storageRepo);
|
||||
bldHlpRender(storageBuild, bldCfg, bldHlpParse(storageRepo, bldCfg));
|
||||
bldHlpRender(storageBuild, bldCfg, bldHlpParse(storageRepo, bldCfg, false));
|
||||
}
|
||||
|
||||
// PostgreSQL
|
||||
|
@ -122,7 +122,7 @@ testRun(void)
|
||||
" </operation>\n"
|
||||
"</doc>\n");
|
||||
|
||||
TEST_ERROR(bldHlpParse(storageTest, bldCfgErr), FormatError, "command 'backup' must have help");
|
||||
TEST_ERROR(bldHlpParse(storageTest, bldCfgErr, false), FormatError, "command 'backup' must have help");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("error on missing config option");
|
||||
@ -153,7 +153,7 @@ testRun(void)
|
||||
" </operation>\n"
|
||||
"</doc>\n");
|
||||
|
||||
TEST_ERROR(bldHlpParse(storageTest, bldCfgErr), FormatError, "option 'buffer' must have help for command 'backup'");
|
||||
TEST_ERROR(bldHlpParse(storageTest, bldCfgErr, false), FormatError, "option 'buffer' must have help for command 'backup'");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("error on missing command-line option");
|
||||
@ -195,7 +195,7 @@ testRun(void)
|
||||
" </operation>\n"
|
||||
"</doc>\n");
|
||||
|
||||
TEST_ERROR(bldHlpParse(storageTest, bldCfgErr), FormatError, "option 'stanza' must have help for command 'backup'");
|
||||
TEST_ERROR(bldHlpParse(storageTest, bldCfgErr, false), FormatError, "option 'stanza' must have help for command 'backup'");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("parse and render");
|
||||
@ -238,6 +238,7 @@ testRun(void)
|
||||
"\n"
|
||||
" force:\n"
|
||||
" type: boolean\n"
|
||||
" internal: true\n"
|
||||
" command:\n"
|
||||
" check: {}\n"
|
||||
" restore: {}\n"
|
||||
@ -266,6 +267,9 @@ testRun(void)
|
||||
" <text>\n"
|
||||
" <p>Buffer.</p>\n"
|
||||
" </text>\n"
|
||||
"\n"
|
||||
" <example>128KiB</example>\n"
|
||||
" <example>256KiB</example>\n"
|
||||
" </config-key>\n"
|
||||
"\n"
|
||||
" <config-key id=\"stanza\" name=\"Stanza\">\n"
|
||||
@ -274,6 +278,8 @@ testRun(void)
|
||||
" <text>\n"
|
||||
" <p>Stanza.</p>\n"
|
||||
" </text>\n"
|
||||
"\n"
|
||||
" <example>test_stanza</example>\n"
|
||||
" </config-key>\n"
|
||||
" </config-key-list>\n"
|
||||
" </config-section>\n"
|
||||
@ -342,7 +348,8 @@ testRun(void)
|
||||
"</doc>\n");
|
||||
|
||||
TEST_RESULT_STR_Z(
|
||||
hrnPackReadToStr(pckReadNew(pckWriteResult(bldHlpRenderHelpAutoCPack(bldCfg, bldHlpParse(storageTest, bldCfg))))),
|
||||
hrnPackReadToStr(
|
||||
pckReadNew(pckWriteResult(bldHlpRenderHelpAutoCPack(bldCfg, bldHlpParse(storageTest, bldCfg, false))))),
|
||||
// {uncrustify_off - indentation}
|
||||
"1:array:"
|
||||
"["
|
||||
@ -376,6 +383,7 @@ testRun(void)
|
||||
"}"
|
||||
"]"
|
||||
// force option
|
||||
", 13:bool:true"
|
||||
", 18:array:"
|
||||
"["
|
||||
// check command override
|
||||
@ -407,7 +415,7 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("check help file");
|
||||
|
||||
TEST_RESULT_VOID(bldHlpRender(storageTest, bldCfg, bldHlpParse(storageTest, bldCfg)), "write file");
|
||||
TEST_RESULT_VOID(bldHlpRender(storageTest, bldCfg, bldHlpParse(storageTest, bldCfg, false)), "write file");
|
||||
TEST_STORAGE_EXISTS(storageTest, "src/command/help/help.auto.c.inc");
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,8 @@ testRun(void)
|
||||
|
||||
// Create help data
|
||||
const BldCfg bldCfg = bldCfgParse(storagePosixNewP(HRN_PATH_REPO_STR));
|
||||
const Buffer *const helpData = bldHlpRenderHelpAutoCCmp(bldCfg, bldHlpParse(storagePosixNewP(HRN_PATH_REPO_STR), bldCfg));
|
||||
const Buffer *const helpData = bldHlpRenderHelpAutoCCmp(
|
||||
bldCfg, bldHlpParse(storagePosixNewP(HRN_PATH_REPO_STR), bldCfg, false));
|
||||
|
||||
// Program name a version are used multiple times
|
||||
const char *helpVersion = PROJECT_NAME " " PROJECT_VERSION;
|
||||
|
Loading…
x
Reference in New Issue
Block a user