From 1d5563288cf1839acb237a188b865ecb01fe97da Mon Sep 17 00:00:00 2001 From: David Steele Date: Fri, 29 Sep 2023 17:28:00 -0400 Subject: [PATCH] Parse defaults and text sections in help.xml. These will be required to build documentation in C. --- doc/xml/dtd/doc.dtd | 4 +-- src/build/config/parse.h | 2 +- src/build/help/help.xml | 10 ++++-- src/build/help/parse.c | 58 ++++++++++++++++++++++++++++-- src/build/help/parse.h | 21 ++++++++++- src/build/main.c | 2 +- test/src/module/build/helpTest.c | 18 +++++++--- test/src/module/command/helpTest.c | 3 +- 8 files changed, 102 insertions(+), 16 deletions(-) diff --git a/doc/xml/dtd/doc.dtd b/doc/xml/dtd/doc.dtd index e85328a51..5b1b76650 100644 --- a/doc/xml/dtd/doc.dtd +++ b/doc/xml/dtd/doc.dtd @@ -25,7 +25,7 @@ - + @@ -45,7 +45,7 @@ - + diff --git a/src/build/config/parse.h b/src/build/config/parse.h index e69042b7c..0b8f6be39 100644 --- a/src/build/config/parse.h +++ b/src/build/config/parse.h @@ -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 diff --git a/src/build/help/help.xml b/src/build/help/help.xml index 0d74197de..f62bb7156 100644 --- a/src/build/help/help.xml +++ b/src/build/help/help.xml @@ -539,7 +539,8 @@

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.

- 7=2|14=4 + 7=2 + 14=4 @@ -549,7 +550,8 @@

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.

- 32KiB=7|128KiB=8 + 32KiB=7 + 128KiB=8
@@ -559,7 +561,9 @@

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.

- 16KiB=8KiB|128KiB=16KiB|512KiB=32KiB + 16KiB=8KiB + 128KiB=16KiB + 512KiB=32KiB
diff --git a/src/build/help/parse.c b/src/build/help/parse.c index 76933ce3b..d3166cbfd 100644 --- a/src/build/help/parse.c +++ b/src/build/help/parse.c @@ -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) }; diff --git a/src/build/help/parse.h b/src/build/help/parse.h index 3cab89b46..d81b93301 100644 --- a/src/build/help/parse.h +++ b/src/build/help/parse.h @@ -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 diff --git a/src/build/main.c b/src/build/main.c index 31bdc343c..9045f3b1d 100644 --- a/src/build/main.c +++ b/src/build/main.c @@ -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 diff --git a/test/src/module/build/helpTest.c b/test/src/module/build/helpTest.c index 7e8d6aeae..c74610459 100644 --- a/test/src/module/build/helpTest.c +++ b/test/src/module/build/helpTest.c @@ -122,7 +122,7 @@ testRun(void) " \n" "\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) " \n" "\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) " \n" "\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) " \n" "

Buffer.

\n" "
\n" + "\n" + " 128KiB\n" + " 256KiB\n" "
\n" "\n" " \n" @@ -274,6 +278,8 @@ testRun(void) " \n" "

Stanza.

\n" "
\n" + "\n" + " test_stanza\n" "
\n" " \n" " \n" @@ -342,7 +348,8 @@ testRun(void) "\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"); } diff --git a/test/src/module/command/helpTest.c b/test/src/module/command/helpTest.c index f68fdc2bb..eab2e5a60 100644 --- a/test/src/module/command/helpTest.c +++ b/test/src/module/command/helpTest.c @@ -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;