1
0
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:
David Steele 2023-09-29 17:28:00 -04:00
parent 088026e6ff
commit 1d5563288c
8 changed files with 102 additions and 16 deletions

View File

@ -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>

View File

@ -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

View File

@ -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">

View File

@ -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)
};

View File

@ -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

View File

@ -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

View File

@ -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");
}

View File

@ -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;