From 56c18c63ed9272256f6fc69e8cfa6bd376122fed Mon Sep 17 00:00:00 2001 From: Tim Bray Date: Tue, 16 Mar 2021 20:40:26 -0700 Subject: [PATCH] Add argument -k to allow continuing after non-fatal errors --- expat/doc/xmlwf.xml | 33 +++++++++++++++++++++++------ expat/xmlwf/xmlwf.c | 41 ++++++++++++++++++++++++++++++++---- expat/xmlwf/xmlwf_helpgen.py | 7 ++++++ 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/expat/doc/xmlwf.xml b/expat/doc/xmlwf.xml index 654466ce..85c6ed57 100644 --- a/expat/doc/xmlwf.xml +++ b/expat/doc/xmlwf.xml @@ -60,6 +60,7 @@ + file ... @@ -293,6 +294,20 @@ supports both. + + + + + When processing multiple files, Expat by default halts after the + the first file with an error. This tells Expat to report the error + but to keep processing. + This can be useful, for example, when testing a filter that converts + many files to XML and you want to quickly find out which conversions + failed. + + + + @@ -379,11 +394,17 @@ supports both. OUTPUT - If an input file is not well-formed, - &dhpackage; prints a single line describing - the problem to standard output. If a file is well formed, - &dhpackage; outputs nothing. - + &dhpackage; outputs nothing for files which are problem-free. + If any input file is not well-formed, or if the output for any + input file cannot be opened, &dhpackage; prints a single + line describing the problem to standard output. + + + If the option is not provided, &dhpackage; + halts upon encountering a well-formedness or output-file error. + If is provided, &dhpackage; continues + processing the remaining input files, describing problems found with any of them. + @@ -392,7 +413,7 @@ supports both. - The input files are well-formed. + The input files are well-formed and the output (if requested) was written successfully. diff --git a/expat/xmlwf/xmlwf.c b/expat/xmlwf/xmlwf.c index 5121fa10..af7dc431 100644 --- a/expat/xmlwf/xmlwf.c +++ b/expat/xmlwf/xmlwf.c @@ -322,6 +322,13 @@ freeNotations(XmlwfUserData *data) { data->notationListHead = NULL; } +static void +cleanupUserData(XmlwfUserData *userData) { + free((void *)userData->currentDoctypeName); + userData->currentDoctypeName = NULL; + freeNotations(userData); +} + static int xcscmp(const XML_Char *xs, const XML_Char *xt) { while (*xs != 0 && *xt != 0) { @@ -848,9 +855,11 @@ usage(const XML_Char *prog, int rc) { stderr, /* Generated with: * $ xmlwf/xmlwf_helpgen.sh + * To update, change xmlwf/xmlwf_helpgen.py, then paste the output of + * xmlwf/xmlwf_helpgen.sh in here. */ /* clang-format off */ - T("usage: %s [-s] [-n] [-p] [-x] [-e ENCODING] [-w] [-r] [-d DIRECTORY]\n") + T("usage: %s [-s] [-n] [-p] [-x] [-e ENCODING] [-w] [-r] [-k] [-d DIRECTORY]\n") T(" [-c | -m | -t] [-N]\n") T(" [FILE [FILE ...]]\n") T("\n") @@ -867,6 +876,7 @@ usage(const XML_Char *prog, int rc) { T(" -e ENCODING override any in-document [e]ncoding declaration\n") T(" -w enable support for [W]indows code pages\n") T(" -r disable memory-mapping and use normal file [r]ead IO calls instead\n") + T(" -k when processing multiple files, [k]eep processing after first file with error\n") T("\n") T("output control arguments:\n") T(" -d DIRECTORY output [d]estination directory\n") @@ -879,6 +889,12 @@ usage(const XML_Char *prog, int rc) { T(" -h show this [h]elp message and exit\n") T(" -v show program's [v]ersion number and exit\n") T("\n") + T("exit status:\n") + T(" 0 the input files are well-formed and the output (if requested) was written successfully\n") + T(" 1 could not allocate data structures, signals a serious problem with execution environment\n") + T(" 2 command-line argument error, or one or more input files were not well-formed\n") + T(" 3 could not create an output file\n") + T("\n") T("xmlwf of libexpat is software libre, licensed under the MIT license.\n") T("Please report bugs at https://github.com/libexpat/libexpat/issues. Thank you!\n") , /* clang-format on */ @@ -902,6 +918,8 @@ tmain(int argc, XML_Char **argv) { int useNamespaces = 0; int requireStandalone = 0; int requiresNotations = 0; + int continueOnError = 0; + int exitCode = 0; enum XML_ParamEntityParsing paramEntityParsing = XML_PARAM_ENTITY_PARSING_NEVER; int useStdin = 0; @@ -990,6 +1008,10 @@ tmain(int argc, XML_Char **argv) { case T('v'): showVersion(argv[0]); return 0; + case T('k'): + continueOnError = 1; + j++; + break; case T('\0'): if (j > 1) { i++; @@ -1061,7 +1083,14 @@ tmain(int argc, XML_Char **argv) { userData.fp = tfopen(outName, T("wb")); if (! userData.fp) { tperror(outName); - exit(3); + exitCode = 3; + if (continueOnError) { + free(outName); + cleanupUserData(&userData); + continue; + } else { + break; + } } setvbuf(userData.fp, NULL, _IOFBF, 16384); #ifdef XML_UNICODE @@ -1123,8 +1152,12 @@ tmain(int argc, XML_Char **argv) { } XML_ParserFree(parser); if (! result) { - exit(2); + exitCode = 2; + cleanupUserData(&userData); + if (! continueOnError) { + break; + } } } - return 0; + return exitCode; } diff --git a/expat/xmlwf/xmlwf_helpgen.py b/expat/xmlwf/xmlwf_helpgen.py index 939286e5..88e3dd6d 100755 --- a/expat/xmlwf/xmlwf_helpgen.py +++ b/expat/xmlwf/xmlwf_helpgen.py @@ -31,6 +31,12 @@ import argparse epilog = """ +exit status: + 0 the input files are well-formed and the output (if requested) was written successfully + 1 could not allocate data structures, signals a serious problem with execution environment + 2 command-line argument error, or one or more input files were not well-formed + 3 could not create an output file + xmlwf of libexpat is software libre, licensed under the MIT license. Please report bugs at https://github.com/libexpat/libexpat/issues. Thank you! """ @@ -48,6 +54,7 @@ input_related.add_argument('-x', action='store_true', help='enable processing of input_related.add_argument('-e', action='store', metavar='ENCODING', help='override any in-document [e]ncoding declaration') input_related.add_argument('-w', action='store_true', help='enable support for [W]indows code pages') input_related.add_argument('-r', action='store_true', help='disable memory-mapping and use normal file [r]ead IO calls instead') +input_related.add_argument('-k', action='store_true', help='when processing multiple files, [k]eep processing after first file with error') output_related = parser.add_argument_group('output control arguments') output_related.add_argument('-d', action='store', metavar='DIRECTORY', help='output [d]estination directory')