..
/
download
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <stdbool.h>
#include <string.h>
#include <libxml/tree.h>
#include <libxslt/xslt.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>
#include "s1kd_tools.h"
#include "stylesheets.h"
#define PROG_NAME "s1kd-neutralize"
#define VERSION "1.11.0"
#define ERR_PREFIX PROG_NAME ": ERROR: "
#define INF_PREFIX PROG_NAME ": INFO: "
#define E_BAD_LIST ERR_PREFIX "Could not read list: %s\n"
#define I_NEUTRALIZE INF_PREFIX "Adding neutral metadata to %s...\n"
static enum verbosity { QUIET, NORMAL, VERBOSE } verbosity = NORMAL;
static void neutralizeFile(const char *fname, const char *outfile, bool overwrite, bool namesp)
{
xmlDocPtr doc, res, styledoc, orig;
xsltStylesheetPtr style;
xmlNodePtr oldroot;
if (verbosity >= VERBOSE) {
fprintf(stderr, I_NEUTRALIZE, fname);
}
orig = read_xml_doc(fname);
doc = xmlCopyDoc(orig, 1);
styledoc = read_xml_mem((const char *) stylesheets_xlink_xsl, stylesheets_xlink_xsl_len);
style = xsltParseStylesheetDoc(styledoc);
res = xsltApplyStylesheet(style, doc, NULL);
xmlFreeDoc(doc);
xsltFreeStylesheet(style);
doc = res;
styledoc = read_xml_mem((const char *) stylesheets_rdf_xsl, stylesheets_rdf_xsl_len);
style = xsltParseStylesheetDoc(styledoc);
res = xsltApplyStylesheet(style, doc, NULL);
xmlFreeDoc(doc);
xsltFreeStylesheet(style);
if (namesp) {
doc = res;
styledoc = read_xml_mem((const char *)
stylesheets_namespace_xsl,
stylesheets_namespace_xsl_len);
style = xsltParseStylesheetDoc(styledoc);
res = xsltApplyStylesheet(style, doc, NULL);
xmlFreeDoc(doc);
xsltFreeStylesheet(style);
}
oldroot = xmlDocGetRootElement(orig);
xmlUnlinkNode(oldroot);
xmlFreeNode(oldroot);
xmlDocSetRootElement(orig, xmlCopyNode(xmlDocGetRootElement(res), 1));
if (overwrite) {
save_xml_doc(orig, fname);
} else {
save_xml_doc(orig, outfile);
}
xmlFreeDoc(res);
xmlFreeDoc(orig);
}
static void neutralizeList(const char *path, const char *outfile, bool overwrite, bool namesp)
{
FILE *f;
char line[PATH_MAX];
if (path) {
if (!(f = fopen(path, "r"))) {
if (verbosity >= NORMAL) {
fprintf(stderr, E_BAD_LIST, path);
}
return;
}
} else {
f = stdin;
}
while (fgets(line, PATH_MAX, f)) {
strtok(line, "\t\r\n");
neutralizeFile(line, outfile, overwrite, namesp);
}
if (path) {
fclose(f);
}
}
static void deneutralizeFile(const char *fname, const char *outfile, bool overwrite)
{
xmlDocPtr doc, res, styledoc, orig;
xsltStylesheetPtr style;
xmlNodePtr oldroot;
if (verbosity >= VERBOSE) {
fprintf(stderr, I_NEUTRALIZE, fname);
}
orig = read_xml_doc(fname);
doc = xmlCopyDoc(orig, 1);
styledoc = read_xml_mem((const char *) stylesheets_delete_xsl, stylesheets_delete_xsl_len);
style = xsltParseStylesheetDoc(styledoc);
res = xsltApplyStylesheet(style, doc, NULL);
xmlFreeDoc(doc);
xsltFreeStylesheet(style);
oldroot = xmlDocGetRootElement(orig);
xmlUnlinkNode(oldroot);
xmlFreeNode(oldroot);
xmlDocSetRootElement(orig, xmlCopyNode(xmlDocGetRootElement(res), 1));
if (overwrite) {
save_xml_doc(orig, fname);
} else {
save_xml_doc(orig, outfile);
}
xmlFreeDoc(res);
xmlFreeDoc(orig);
}
static void deneutralizeList(const char *path, const char *outfile, bool overwrite)
{
FILE *f;
char line[PATH_MAX];
if (path) {
if (!(f = fopen(path, "r"))) {
if (verbosity >= NORMAL) {
fprintf(stderr, E_BAD_LIST, path);
}
return;
}
} else {
f = stdin;
}
while (fgets(line, PATH_MAX, f)) {
strtok(line, "\t\r\n");
deneutralizeFile(line, outfile, overwrite);
}
if (path) {
fclose(f);
}
}
static void show_help(void)
{
puts("Usage: " PROG_NAME " [-o <file>] [-Dflnqvh?] [<object>...]");
puts("");
puts("Options:");
puts(" -D, --delete Remove neutral metadata.");
puts(" -f, --overwrite Overwrite CSDB objects automatically.");
puts(" -h, -?, --help Show usage message.");
puts(" -l, --list Treat input as list of CSDB objects.");
puts(" -n, --namespace Include IETP namespaces on elements.");
puts(" -o, --out <file> Output to <file> instead of stdout.");
puts(" -q, --quiet Quiet mode.");
puts(" -v, --verbose Verbose output.");
puts(" --version Show version information.");
LIBXML2_PARSE_LONGOPT_HELP
}
static void show_version(void)
{
printf("%s (s1kd-tools) %s\n", PROG_NAME, VERSION);
printf("Using libxml %s and libxslt %s\n", xmlParserVersion, xsltEngineVersion);
}
int main(int argc, char **argv)
{
int i;
char *outfile = strdup("-");
bool overwrite = false;
bool islist = false;
bool namesp = false;
bool delete = false;
const char *sopts = "Dflno:qvh?";
struct option lopts[] = {
{"version" , no_argument , 0, 0},
{"help" , no_argument , 0, 'h'},
{"delete" , no_argument , 0, 'D'},
{"overwrite", no_argument , 0, 'f'},
{"list" , no_argument , 0, 'l'},
{"namespace", no_argument , 0, 'n'},
{"out" , required_argument, 0, 'o'},
{"quiet" , no_argument , 0, 'q'},
{"verbose" , no_argument , 0, 'v'},
LIBXML2_PARSE_LONGOPT_DEFS
{0, 0, 0, 0}
};
int loptind = 0;
while ((i = getopt_long(argc, argv, sopts, lopts, &loptind)) != -1) {
switch (i) {
case 0:
if (strcmp(lopts[loptind].name, "version") == 0) {
show_version();
return 0;
}
LIBXML2_PARSE_LONGOPT_HANDLE(lopts, loptind, optarg)
break;
case 'D':
delete = true;
break;
case 'f':
overwrite = true;
break;
case 'l':
islist = true;
break;
case 'n':
namesp = true;
break;
case 'o':
free(outfile);
outfile = strdup(optarg);
break;
case 'q':
--verbosity;
break;
case 'v':
++verbosity;
break;
case 'h':
case '?':
show_help();
exit(0);
}
}
if (delete) {
if (optind < argc) {
for (i = optind; i < argc; ++i) {
if (islist) {
deneutralizeList(argv[i], outfile, overwrite);
} else {
deneutralizeFile(argv[i], outfile, overwrite);
}
}
} else if (islist) {
deneutralizeList(NULL, outfile, overwrite);
} else {
deneutralizeFile("-", outfile, false);
}
} else {
if (optind < argc) {
for (i = optind; i < argc; ++i) {
if (islist) {
neutralizeList(argv[i], outfile, overwrite, namesp);
} else {
neutralizeFile(argv[i], outfile, overwrite, namesp);
}
}
} else if (islist) {
neutralizeList(NULL, outfile, overwrite, namesp);
} else {
neutralizeFile("-", outfile, false, namesp);
}
}
free(outfile);
xsltCleanupGlobals();
xmlCleanupParser();
return 0;
}
gopher://khzae.net/0/s1000d/s1kd-tools/src/tools/s1kd-neutralize/s1kd-neutralize.c