Skip to content

Commit

Permalink
s1kd-validate: Add -T (--summary) option
Browse files Browse the repository at this point in the history
Added a -T (--summary) option which prints out a summary with statistics
on the number of documents that passed/failed validation after it
completes. This is analogous to the -T option in s1kd-brexcheck and
s1kd-appcheck.
  • Loading branch information
kibook committed Dec 26, 2024
1 parent 2f2edf9 commit b0cb3c0
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 17 deletions.
9 changes: 6 additions & 3 deletions tools/s1kd-validate/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ endif

warning_flags = -Wall -Werror -pedantic-errors

CFLAGS = $(warning_flags) -I $(common_dir) `pkg-config --cflags libxml-2.0`
CFLAGS = $(warning_flags) -I $(common_dir) `pkg-config --cflags libxml-2.0 libxslt`

ifneq ($(MSYSTEM),)
CFLAGS += -isystem $(common_dir)/msys
Expand All @@ -24,7 +24,7 @@ else
CFLAGS += -O3
endif

LDFLAGS = `pkg-config --libs libxml-2.0`
LDFLAGS = `pkg-config --libs libxml-2.0 libxslt`

prefix = /usr/local
exec_prefix = $(prefix)
Expand All @@ -34,7 +34,10 @@ INSTALL = install -Ds

all: $(executable)

$(executable): $(sources)
stats.h: stats.xsl
xxd -i $+ > $@

$(executable): $(sources) stats.h
$(CC) $(CFLAGS) -o $(executable) $(sources) $(LDFLAGS)

docs:
Expand Down
6 changes: 5 additions & 1 deletion tools/s1kd-validate/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ s1kd-validate - Validate S1000D CSDB objects against their schemas

# SYNOPSIS

s1kd-validate [-s <path>] [-X <URI>] [-F|-f] [-o|-x] [-elqv^h?]
s1kd-validate [-s <path>] [-X <URI>] [-F|-f] [-o|-x] [-elqTv^h?]
[<object>...]

# DESCRIPTION
Expand Down Expand Up @@ -42,6 +42,10 @@ schemas.
Validate the objects against the specified schema, rather than the
one that they reference.

- \-T, --summary
Print a summary of the validation after it completes, including
statistics on the number of documents that passed/failed.

- \-v, --verbose
Verbose mode. Success/failure will be explicitly reported on top of
any errors.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@
<reasonForUpdate id="rfu-change-exclude" updateHighlight="1" updateReasonType="urt02">
<simplePara>Change --exclude short option to -X.</simplePara>
</reasonForUpdate>
<reasonForUpdate id="rfu-summary" updateHighlight="1" updateReasonType="urt02">
<simplePara>Add -T (--summary) option.</simplePara>
</reasonForUpdate>
</dmStatus>
</identAndStatusSection>
<content>
Expand All @@ -55,7 +58,7 @@
<levelledPara>
<title>SYNOPSIS</title>
<para>
<verbatimText verbatimStyle="vs24" changeMark="1" changeType="modify" reasonForUpdateRefIds="rfu-xml-report rfu-change-exclude"><![CDATA[s1kd-validate [-s <path>] [-X <URI>] [-F|-f] [-o|-x] [-elqv^h?]
<verbatimText verbatimStyle="vs24" changeMark="1" changeType="modify" reasonForUpdateRefIds="rfu-xml-report rfu-change-exclude rfu-summary"><![CDATA[s1kd-validate [-s <path>] [-X <URI>] [-F|-f] [-o|-x] [-elqTv^h?]
[<object>...]]]></verbatimText>
</para>
</levelledPara>
Expand Down Expand Up @@ -115,6 +118,12 @@
<para>Validate the objects against the specified schema, rather than the one that they reference.</para>
</listItemDefinition>
</definitionListItem>
<definitionListItem changeMark="1" changeType="add" reasonForUpdateRefIds="rfu-summary">
<listItemTerm>-T, --summary</listItemTerm>
<listItemDefinition>
<para>Print a summary of the validation after it completes, including statistics on the number of documents that passed/failed.</para>
</listItemDefinition>
</definitionListItem>
<definitionListItem>
<listItemTerm>-v, --verbose</listItemTerm>
<listItemDefinition>
Expand Down
8 changes: 7 additions & 1 deletion tools/s1kd-validate/doc/s1kd-validate.1
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ s1kd\-validate \- Validate S1000D CSDB objects against their schemas
.IP
.nf
\f[C]
s1kd\-validate\ [\-s\ <path>]\ [\-X\ <URI>]\ [\-F|\-f]\ [\-o|\-x]\ [\-elqv^h?]
s1kd\-validate\ [\-s\ <path>]\ [\-X\ <URI>]\ [\-F|\-f]\ [\-o|\-x]\ [\-elqTv^h?]
\ \ \ \ \ \ \ \ \ \ \ \ \ \ [<object>...]
\f[]
.fi
Expand Down Expand Up @@ -64,6 +64,12 @@ that they reference.
.RS
.RE
.TP
.B \-T, \-\-summary
Print a summary of the validation after it completes, including
statistics on the number of documents that passed/failed.
.RS
.RE
.TP
.B \-v, \-\-verbose
Verbose mode.
Success/failure will be explicitly reported on top of any errors.
Expand Down
55 changes: 44 additions & 11 deletions tools/s1kd-validate/s1kd-validate.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
#include <libxml/tree.h>
#include <libxml/xmlschemas.h>
#include <libxml/debugXML.h>
#include <libxslt/transform.h>
#include "s1kd_tools.h"
#include "stats.h"

#define PROG_NAME "s1kd-validate"
#define VERSION "4.1.1"
#define VERSION "4.2.0"

#define ERR_PREFIX PROG_NAME ": ERROR: "
#define SUCCESS_PREFIX PROG_NAME ": SUCCESS: "
Expand Down Expand Up @@ -189,7 +191,7 @@ static struct s1kd_schema_parser *add_schema_parser(char *url)

static void show_help(void)
{
puts("Usage: " PROG_NAME " [-s <path>] [-X <URI>] [-F|-f] [-o|-x] [-elqv^h?] [<object>...]");
puts("Usage: " PROG_NAME " [-s <path>] [-X <URI>] [-F|-f] [-o|-x] [-elqTv^h?] [<object>...]");
puts("");
puts("Options:");
puts(" -e, --ignore-empty Ignore empty/non-XML documents.");
Expand All @@ -200,6 +202,7 @@ static void show_help(void)
puts(" -o, --output-valid Output valid CSDB objects to stdout.");
puts(" -q, --quiet Silent (no output).");
puts(" -s, --schema <path> Validate against the given schema.");
puts(" -T, --summary Print a summary of the check.");
puts(" -v, --verbose Verbose output.");
puts(" -X, --exclude <URI> Exclude namespace from validation by URI.");
puts(" -x, --xml Output an XML report.");
Expand All @@ -212,7 +215,7 @@ static void show_help(void)
static void show_version(void)
{
printf("%s (s1kd-tools) %s\n", PROG_NAME, VERSION);
printf("Using libxml %s\n", xmlParserVersion);
printf("Using libxml %s and libxslt %s\n", xmlParserVersion, xsltEngineVersion);
}

static void add_ignore_ns(xmlNodePtr ignore_ns, const char *arg)
Expand Down Expand Up @@ -485,6 +488,23 @@ static int validate_file_list(const char *fname, const char *schema, xmlNodePtr
return err;
}

static void print_stats()
{
xmlDocPtr styledoc;
xsltStylesheetPtr style;
xmlDocPtr res;

styledoc = read_xml_mem((const char *) stats_xsl, stats_xsl_len);
style = xsltParseStylesheetDoc(styledoc);

res = xsltApplyStylesheet(style, xml_report_doc, NULL);

fprintf(stderr, "%s", (char *) res->children->content);

xmlFreeDoc(res);
xsltFreeStylesheet(style);
}

int main(int argc, char *argv[])
{
int c, i;
Expand All @@ -494,10 +514,12 @@ int main(int argc, char *argv[])
int ignore_empty = 0;
int rem_del = 0;
char *schema = NULL;
int xml = 0;
int show_stats = 0;

xmlNodePtr ignore_ns;

const char *sopts = "vqX:xFfloes:^h?";
const char *sopts = "vqX:xFfloes:T^h?";
struct option lopts[] = {
{"version" , no_argument , 0, 0},
{"help" , no_argument , 0, 'h'},
Expand All @@ -510,6 +532,7 @@ int main(int argc, char *argv[])
{"exclude" , required_argument, 0, 'X'},
{"ignore-empty" , no_argument , 0, 'e'},
{"schema" , required_argument, 0, 's'},
{"summary" , no_argument , 0, 'T'},
{"xml" , no_argument , 0, 'x'},
{"remove-deleted" , no_argument , 0, '^'},
LIBXML2_PARSE_LONGOPT_DEFS
Expand Down Expand Up @@ -540,10 +563,8 @@ int main(int argc, char *argv[])
case 'e': ignore_empty = 1; break;
case 's': schema = strdup(optarg); break;
case '^': rem_del = 1; break;
case 'x':
xml_report_doc = xmlNewDoc(BAD_CAST "1.0");
xmlDocSetRootElement(xml_report_doc, xmlNewNode(NULL, BAD_CAST "s1kdValidateReport"));
break;
case 'T': show_stats = 1; break;
case 'x': xml = 1; break;
case 'h':
case '?': show_help(); return EXIT_SUCCESS;
}
Expand All @@ -558,6 +579,11 @@ int main(int argc, char *argv[])
/* FIXME: This function is deprecated, is it still needed here when we set per-context error handlers as well? */
xmlSetStructuredErrorFunc(NULL, schema_errfunc);

if (xml || show_stats) {
xml_report_doc = xmlNewDoc(BAD_CAST "1.0");
xmlDocSetRootElement(xml_report_doc, xmlNewNode(NULL, BAD_CAST "s1kdValidateReport"));
}

if (optind < argc) {
for (i = optind; i < argc; ++i) {
if (is_list) {
Expand All @@ -582,12 +608,19 @@ int main(int argc, char *argv[])
free(schema_parsers);
xmlFreeNode(ignore_ns);
free(schema);
xmlCleanupParser();

if (xml_report_doc) {
if (xml) {
save_xml_doc(xml_report_doc, "-");
xmlFreeDoc(xml_report_doc);
}

if (show_stats) {
print_stats(xml_report_doc);
}

xmlFreeDoc(xml_report_doc);

xsltCleanupGlobals();
xmlCleanupParser();

return err ? EXIT_FAILURE : EXIT_SUCCESS;
}
35 changes: 35 additions & 0 deletions tools/s1kd-validate/stats.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">

<xsl:output method="text"/>

<xsl:template match="s1kdValidateReport">
<xsl:variable name="total" select="count(document)"/>
<xsl:text>Total documents checked: </xsl:text>
<xsl:value-of select="$total"/>
<xsl:text>&#10;</xsl:text>
<xsl:if test="$total &gt; 0">
<xsl:variable name="errors" select="count(document/error)"/>
<xsl:variable name="fail" select="count(document[error])"/>
<xsl:variable name="pass" select="count(document[not(error)])"/>
<xsl:text>Total errors: </xsl:text>
<xsl:value-of select="$errors"/>
<xsl:text>&#10;</xsl:text>
<xsl:text>Total documents that pass the check: </xsl:text>
<xsl:value-of select="$pass"/>
<xsl:text>&#10;</xsl:text>
<xsl:text>Total documents that fail the check: </xsl:text>
<xsl:value-of select="$fail"/>
<xsl:text>&#10;</xsl:text>
<xsl:text>Percentage passed: </xsl:text>
<xsl:value-of select="floor($pass div $total * 100)"/>
<xsl:text>%&#10;</xsl:text>
<xsl:text>Percentage failed: </xsl:text>
<xsl:value-of select="ceiling($fail div $total * 100)"/>
<xsl:text>%&#10;</xsl:text>
</xsl:if>
</xsl:template>

</xsl:stylesheet>

0 comments on commit b0cb3c0

Please sign in to comment.