..
/
download
#include <stdio.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <stdbool.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
#include <libxml/xpathInternals.h>
#include <libxslt/xsltInternals.h>
#include <libxslt/xslt.h>
#include <libxslt/transform.h>
#include <libxslt/xsltutils.h>
#include "stylesheets.h"
#include "s1kd_tools.h"
#define PROG_NAME "s1kd-acronyms"
#define VERSION "1.14.0"
/* Paths to text nodes where acronyms may occur */
#define ACRO_MARKUP_XPATH BAD_CAST "//para/text()|//notePara/text()|//warningAndCautionPara/text()|//attentionListItemPara/text()|//title/text()|//listItemTerm/text()|//term/text()|//termTitle/text()|//emphasis/text()|//changeInline/text()|//change/text()"
static xmlChar *acro_markup_xpath = NULL;
/* Characters that must occur before/after a set of characters in order for the
* set to be considered a valid acronym. */
#define PRE_ACRONYM_DELIM BAD_CAST " (/\"'\n"
#define POST_ACRONYM_DELIM BAD_CAST " .,)/?!:\"'\n"
#define ERR_PREFIX PROG_NAME ": ERROR: "
#define INF_PREFIX PROG_NAME ": INFO: "
#define E_NO_LIST ERR_PREFIX "Could not read acronyms list: %s\n"
#define E_NO_FILE ERR_PREFIX "Could not read file: %s\n"
#define E_BAD_LIST ERR_PREFIX "Could not read list file: %s\n"
#define I_FIND INF_PREFIX "Searching for acronyms in %s...\n"
#define I_MARKUP INF_PREFIX "Marking up acronyms in %s...\n"
#define I_DELETE INF_PREFIX "Deleting acronym markup in %s...\n"
#define I_PREFORMAT INF_PREFIX "Preformatting acronyms in %s...\n"
#define EXIT_NO_LIST 1
static bool prettyPrint = false;
static int minimumSpaces = 2;
static enum xmlFormat { BASIC, DEFLIST, TABLE } xmlFormat = BASIC;
static bool interactive = false;
static bool alwaysAsk = false;
static bool deferChoice = false;
static enum verbosity { QUIET, NORMAL, VERBOSE } verbosity = NORMAL;
static xmlNodePtr defaultChoices;
static bool remDelete = false;
static xsltStylesheetPtr termStylesheet, idStylesheet;
static void combineAcronymLists(xmlNodePtr dst, xmlNodePtr src)
{
xmlNodePtr cur;
for (cur = src->children; cur; cur = cur->next) {
if (strcmp((char *) cur->name, "acronym") == 0) {
xmlAddChild(dst, xmlCopyNode(cur, 1));
}
}
}
static void findAcronymsInFile(xmlNodePtr acronyms, const char *path)
{
xmlDocPtr doc, styleDoc, result;
xsltStylesheetPtr style;
if (verbosity >= VERBOSE) {
fprintf(stderr, I_FIND, path);
}
if (!(doc = read_xml_doc(path))) {
if (verbosity >= NORMAL) {
fprintf(stderr, E_NO_FILE, path);
}
return;
}
if (remDelete) {
rem_delete_elems(doc);
}
styleDoc = read_xml_mem((const char *) stylesheets_acronyms_xsl, stylesheets_acronyms_xsl_len);
style = xsltParseStylesheetDoc(styleDoc);
result = xsltApplyStylesheet(style, doc, NULL);
xmlFreeDoc(doc);
xsltFreeStylesheet(style);
combineAcronymLists(acronyms, xmlDocGetRootElement(result));
xmlFreeDoc(result);
}
static xmlDocPtr removeNonUniqueAcronyms(xmlDocPtr doc)
{
xmlDocPtr styleDoc, result;
xsltStylesheetPtr style;
styleDoc = read_xml_mem((const char *) stylesheets_unique_xsl, stylesheets_unique_xsl_len);
style = xsltParseStylesheetDoc(styleDoc);
result = xsltApplyStylesheet(style, doc, NULL);
xmlFreeDoc(doc);
xsltFreeStylesheet(style);
return result;
}
static xmlNodePtr findChild(xmlNodePtr parent, const char *name)
{
xmlNodePtr cur;
for (cur = parent->children; cur; cur = cur->next) {
if (strcmp((char *) cur->name, name) == 0) {
return cur;
}
}
return NULL;
}
static int longestAcronymTerm(xmlNodePtr acronyms)
{
xmlNodePtr cur;
int longest = 0;
for (cur = acronyms->children; cur; cur = cur->next) {
if (strcmp((char *) cur->name, "acronym") == 0) {
char *term;
int len;
term = (char *) xmlNodeGetContent(findChild(cur, "acronymTerm"));
len = strlen(term);
xmlFree(term);
longest = len > longest ? len : longest;
}
}
return longest;
}
static void printAcronyms(xmlNodePtr acronyms, const char *path)
{
xmlNodePtr cur;
int longest = 0;
FILE *out;
if (strcmp(path, "-") == 0)
out = stdout;
else
out = fopen(path, "w");
if (prettyPrint)
longest = longestAcronymTerm(acronyms);
for (cur = acronyms->children; cur; cur = cur->next) {
if (strcmp((char *) cur->name, "acronym") == 0) {
char *term = (char *) xmlNodeGetContent(findChild(cur, "acronymTerm"));
char *defn = (char *) xmlNodeGetContent(findChild(cur, "acronymDefinition"));
char *type = (char *) xmlGetProp(cur, BAD_CAST "acronymType");
if (prettyPrint) {
int len, nspaces, i;
len = strlen(term);
nspaces = longest - len + minimumSpaces;
fprintf(out, "%s", term);
for (i = 0; i < nspaces; ++i) {
fputc(' ', out);
}
if (type) {
fprintf(out, "%s", type);
} else {
fprintf(out, " ");
}
for (i = 0; i < minimumSpaces; ++i) {
fputc(' ', out);
}
fprintf(out, "%s\n", defn);
} else {
fprintf(out, "%s\t", term);
if (type) {
fprintf(out, "%s\t", type);
} else {
fprintf(out, " \t");
}
fprintf(out, "%s\n", defn);
}
xmlFree(term);
xmlFree(defn);
xmlFree(type);
}
}
if (out != stdout)
fclose(out);
}
static xmlDocPtr formatXmlAs(xmlDocPtr doc, unsigned char *src, unsigned int len)
{
xmlDocPtr styleDoc, result;
xsltStylesheetPtr style;
styleDoc = read_xml_mem((const char *) src, len);
style = xsltParseStylesheetDoc(styleDoc);
result = xsltApplyStylesheet(style, doc, NULL);
xmlFreeDoc(doc);
xsltFreeStylesheet(style);
return result;
}
static xmlDocPtr limitToTypes(xmlDocPtr doc, const char *types)
{
xmlDocPtr styleDoc, result;
xsltStylesheetPtr style;
const char *params[3];
char *typesParam;
typesParam = malloc(strlen(types) + 3);
sprintf(typesParam, "'%s'", types);
params[0] = "types";
params[1] = typesParam;
params[2] = NULL;
styleDoc = read_xml_mem((const char *) stylesheets_types_xsl, stylesheets_types_xsl_len);
style = xsltParseStylesheetDoc(styleDoc);
result = xsltApplyStylesheet(style, doc, params);
free(typesParam);
xmlFreeDoc(doc);
xsltFreeStylesheet(style);
return result;
}
static xmlNodePtr firstXPathNode(char *xpath, xmlNodePtr from)
{
xmlXPathContextPtr ctx;
xmlXPathObjectPtr obj;
xmlNodePtr node;
ctx = xmlXPathNewContext(from->doc);
ctx->node = from;
obj = xmlXPathEvalExpression(BAD_CAST xpath, ctx);
if (xmlXPathNodeSetIsEmpty(obj->nodesetval))
node = NULL;
else
node = obj->nodesetval->nodeTab[0];
xmlXPathFreeObject(obj);
xmlXPathFreeContext(ctx);
return node;
}
static xmlNodePtr chooseAcronym(xmlNodePtr acronym, const xmlChar *term, const xmlChar *content)
{
xmlXPathContextPtr ctx;
xmlXPathObjectPtr obj;
bool noDefault = true;
ctx = xmlXPathNewContext(defaultChoices->doc);
xmlXPathRegisterVariable(ctx, BAD_CAST "term", xmlXPathNewString(BAD_CAST term));
obj = xmlXPathEvalExpression(BAD_CAST "//acronym[acronymTerm=$term]", ctx);
if (xmlXPathNodeSetIsEmpty(obj->nodesetval)) {
xmlXPathFreeObject(obj);
xmlXPathFreeContext(ctx);
ctx = xmlXPathNewContext(acronym->doc);
xmlXPathRegisterVariable(ctx, BAD_CAST "term", xmlXPathNewString(BAD_CAST term));
obj = xmlXPathEvalExpression(BAD_CAST "//acronym[acronymTerm=$term]", ctx);
} else {
noDefault = false;
if (xmlHasProp(obj->nodesetval->nodeTab[0], BAD_CAST "ignore")) {
acronym = NULL;
} else {
acronym = obj->nodesetval->nodeTab[0];
}
}
if (deferChoice) {
int i;
acronym = xmlNewNode(NULL, BAD_CAST "chooseAcronym");
for (i = 0; i < obj->nodesetval->nodeNr; ++i) {
xmlAddChild(acronym, xmlCopyNode(obj->nodesetval->nodeTab[i], 1));
}
} else if (noDefault && (alwaysAsk || obj->nodesetval->nodeNr > 1)) {
int i;
printf("Found acronym term %s in the following context:\n\n", (char *) term);
printf("%s\n\n", (char *) content);
puts("Choose definition:");
for (i = 0; i < obj->nodesetval->nodeNr && i < 9; ++i) {
xmlNodePtr acronymDefinition = firstXPathNode("acronymDefinition", obj->nodesetval->nodeTab[i]);
xmlChar *definition = xmlNodeGetContent(acronymDefinition);
printf("%d) %s\n", i + 1, (char *) definition);
xmlFree(definition);
}
puts("s) Ignore this one");
puts("");
puts("Add 'a' after your choice to apply to all remaining occurrences of this acronym");
puts("");
printf("Choice: ");
fflush(stdout);
i = getchar();
if (isdigit(i)) {
acronym = obj->nodesetval->nodeTab[i - '0' - 1];
} else {
acronym = NULL;
}
/* If the choice is followed by 'a', apply to all remaining acronyms. */
if ((i = getchar()) == 'a') {
/* If a definition was chosen, use that as the default. */
if (acronym) {
xmlAddChild(defaultChoices, xmlCopyNode(acronym, 1));
/* If the acronym was ignored, ignore all remaining same acronyms. */
} else {
xmlNodePtr n;
n = xmlNewChild(defaultChoices, NULL, BAD_CAST "acronym", NULL);
xmlSetProp(n, BAD_CAST "ignore", BAD_CAST "1");
xmlNewTextChild(n, NULL, BAD_CAST "acronymTerm", term);
}
} else {
ungetc(i, stdin);
}
while ((i = getchar()) != EOF && i != '\n');
putchar('\n');
}
xmlXPathFreeObject(obj);
xmlXPathFreeContext(ctx);
return acronym;
}
static bool isAcronymTerm(const xmlChar *content, int contentLen, int i, const xmlChar *term, int termLen)
{
bool isTerm;
xmlChar s, e;
s = i == 0 ? ' ' : content[i - 1];
e = i + termLen >= contentLen ? ' ' : content[i + termLen];
isTerm = xmlStrchr(PRE_ACRONYM_DELIM, s) &&
xmlStrncmp(content + i, term, termLen) == 0 &&
xmlStrchr(POST_ACRONYM_DELIM, e);
return isTerm;
}
static void markupAcronymInNode(xmlNodePtr node, xmlNodePtr acronym, const xmlChar *term, int termLen)
{
xmlChar *content;
int contentLen;
int i;
/* Skip empty nodes. */
if (!(content = xmlNodeGetContent(node))) {
return;
}
if ((contentLen = xmlStrlen(content)) == 0) {
xmlFree(content);
return;
}
i = 0;
while (i + termLen <= contentLen) {
if (isAcronymTerm(content, contentLen, i, term, termLen)) {
xmlChar *s1 = xmlStrndup(content, i);
xmlChar *s2 = xmlStrsub(content, i + termLen, contentLen - (i + termLen));
xmlNodePtr acr = acronym;
if (interactive) {
acr = chooseAcronym(acronym, term, content);
}
xmlFree(content);
xmlNodeSetContent(node, s1);
xmlFree(s1);
if (acr) {
acr = xmlAddNextSibling(node, xmlCopyNode(acr, 1));
} else {
acr = xmlAddNextSibling(node, xmlNewNode(NULL, BAD_CAST "ignoredAcronym"));
xmlNodeSetContent(acr, term);
}
node = xmlAddNextSibling(acr, xmlNewText(s2));
content = s2;
contentLen = xmlStrlen(s2);
i = 0;
} else {
++i;
}
}
xmlFree(content);
}
static void markupAcronyms(xmlDocPtr doc, xmlNodePtr acronyms)
{
xmlNodePtr cur;
for (cur = acronyms->children; cur; cur = cur->next) {
if (xmlStrcmp(cur->name, BAD_CAST "acronym") == 0) {
xmlXPathContextPtr ctx;
xmlXPathObjectPtr obj;
xmlChar *term;
int termLen;
/* Skip acronyms with empty terms. */
if (!(term = xmlNodeGetContent(firstXPathNode("acronymTerm", cur)))) {
continue;
}
if ((termLen = xmlStrlen(term)) == 0) {
xmlFree(term);
continue;
}
ctx = xmlXPathNewContext(doc);
obj = xmlXPathEvalExpression(acro_markup_xpath, ctx);
if (!xmlXPathNodeSetIsEmpty(obj->nodesetval)) {
int i;
for (i = 0; i < obj->nodesetval->nodeNr; ++i) {
markupAcronymInNode(obj->nodesetval->nodeTab[i], cur, term, termLen);
}
}
xmlXPathFreeObject(obj);
xmlXPathFreeContext(ctx);
xmlFree(term);
}
}
}
static xmlDocPtr matchAcronymTerms(xmlDocPtr doc)
{
xmlDocPtr res, orig;
xmlNodePtr old;
orig = xmlCopyDoc(doc, 1);
res = xsltApplyStylesheet(termStylesheet, doc, NULL);
xmlFreeDoc(doc);
doc = res;
res = xsltApplyStylesheet(idStylesheet, doc, NULL);
xmlFreeDoc(doc);
old = xmlDocSetRootElement(orig, xmlCopyNode(xmlDocGetRootElement(res), 1));
xmlFreeNode(old);
xmlFreeDoc(res);
return orig;
}
static void transformDoc(xmlDocPtr doc, unsigned char *xsl, unsigned int len)
{
xmlDocPtr styledoc, src, res;
xsltStylesheetPtr style;
xmlNodePtr old;
src = xmlCopyDoc(doc, 1);
styledoc = read_xml_mem((const char *) xsl, len);
style = xsltParseStylesheetDoc(styledoc);
res = xsltApplyStylesheet(style, src, NULL);
old = xmlDocSetRootElement(doc, xmlCopyNode(xmlDocGetRootElement(res), 1));
xmlFreeNode(old);
xmlFreeDoc(src);
xmlFreeDoc(res);
xsltFreeStylesheet(style);
}
static void convertToIssue30(xmlDocPtr doc)
{
transformDoc(doc, stylesheets_30_xsl, stylesheets_30_xsl_len);
}
static void markupAcronymsInFile(const char *path, xmlNodePtr acronyms, const char *out)
{
xmlDocPtr doc;
if (verbosity >= VERBOSE) {
fprintf(stderr, I_MARKUP, path);
}
if (!(doc = read_xml_doc(path))) {
if (verbosity >= NORMAL) {
fprintf(stderr, E_NO_FILE, path);
}
return;
}
markupAcronyms(doc, acronyms);
doc = matchAcronymTerms(doc);
if (xmlStrcmp(xmlFirstElementChild(xmlDocGetRootElement(doc))->name, BAD_CAST "idstatus") == 0) {
convertToIssue30(doc);
}
save_xml_doc(doc, out);
xmlFreeDoc(doc);
}
static xmlDocPtr sortAcronyms(xmlDocPtr doc)
{
xmlDocPtr sortdoc;
xsltStylesheetPtr sort;
xmlDocPtr sorted;
sortdoc = read_xml_mem((const char *) stylesheets_sort_xsl, stylesheets_sort_xsl_len);
sort = xsltParseStylesheetDoc(sortdoc);
sorted = xsltApplyStylesheet(sort, doc, NULL);
xmlFreeDoc(doc);
xsltFreeStylesheet(sort);
return sorted;
}
static void markupAcronymsInList(const char *fname, xmlNodePtr acronyms, const char *out, bool overwrite)
{
FILE *f;
char line[PATH_MAX];
if (fname) {
if (!(f = fopen(fname, "r"))) {
if (verbosity >= NORMAL) {
fprintf(stderr, E_BAD_LIST, fname);
}
return;
}
} else {
f = stdin;
}
while (fgets(line, PATH_MAX, f)) {
strtok(line, "\t\r\n");
if (overwrite) {
markupAcronymsInFile(line, acronyms, line);
} else {
markupAcronymsInFile(line, acronyms, out);
}
}
fclose(f);
}
static void findAcronymsInList(xmlNodePtr acronyms, const char *fname)
{
FILE *f;
char line[PATH_MAX];
if (fname) {
if (!(f = fopen(fname, "r"))) {
if (verbosity >= NORMAL) {
fprintf(stderr, E_BAD_LIST, fname);
}
return;
}
} else {
f = stdin;
}
while (fgets(line, PATH_MAX, f)) {
strtok(line, "\t\r\n");
findAcronymsInFile(acronyms, line);
}
fclose(f);
}
static void deleteAcronyms(xmlDocPtr doc)
{
transformDoc(doc, stylesheets_delete_xsl, stylesheets_delete_xsl_len);
}
static void deleteAcronymsInFile(const char *fname, const char *out)
{
xmlDocPtr doc;
if (verbosity >= VERBOSE) {
fprintf(stderr, I_DELETE, fname);
}
doc = read_xml_doc(fname);
deleteAcronyms(doc);
save_xml_doc(doc, out);
xmlFreeDoc(doc);
}
static void deleteAcronymsInList(const char *fname, const char *out, bool overwrite)
{
FILE *f;
char line[PATH_MAX];
if (fname) {
if (!(f = fopen(fname, "r"))) {
if (verbosity >= NORMAL) {
fprintf(stderr, E_BAD_LIST, fname);
}
return;
}
} else {
f = stdin;
}
while (fgets(line, PATH_MAX, f)) {
strtok(line, "\t\r\n");
if (overwrite) {
deleteAcronymsInFile(line, line);
} else {
deleteAcronymsInFile(line, out);
}
}
fclose(f);
}
static void preformatAcronyms(xmlDocPtr doc)
{
transformDoc(doc, stylesheets_prefmt_xsl, stylesheets_prefmt_xsl_len);
}
static void preformatAcronymsInFile(const char *fname, const char *out)
{
xmlDocPtr doc;
if (verbosity >= VERBOSE) {
fprintf(stderr, I_PREFORMAT, fname);
}
doc = read_xml_doc(fname);
preformatAcronyms(doc);
save_xml_doc(doc, out);
xmlFreeDoc(doc);
}
static void preformatAcronymsInList(const char *fname, const char *out, bool overwrite)
{
FILE *f;
char line[PATH_MAX];
if (fname) {
if (!(f = fopen(fname, "r"))) {
if (verbosity >= NORMAL) {
fprintf(stderr, E_BAD_LIST, fname);
}
return;
}
} else {
f = stdin;
}
while (fgets(line, PATH_MAX, f)) {
strtok(line, "\t\r\n");
if (overwrite) {
preformatAcronymsInFile(line, line);
} else {
preformatAcronymsInFile(line, out);
}
}
fclose(f);
}
static void show_help(void)
{
puts("Usage:");
puts(" " PROG_NAME " -h?");
puts(" " PROG_NAME " [-dlpqtvx^] [-n <#>] [-o <file>] [-T <types>] [<dmodule>...]");
puts(" " PROG_NAME " [-flqv] [-i|-I|-!] [-m|-M <list>] [-o <file>] [-X <xpath>] [<dmodule>...]");
puts(" " PROG_NAME " [-D|-P] [-flqv] [-o <file>] [<dmodule>...]");
puts("");
puts("Options:");
puts(" -D, --delete Remove acronym markup.");
puts(" -d, --deflist Format XML output as definitionList.");
puts(" -f, --overwrite Overwrite data modules when marking up acronyms.");
puts(" -h, -?, --help Show usage message.");
puts(" -I, --always-ask Prompt for all acronyms in interactive mode.");
puts(" -i, --interactive Markup acronyms in interactive mode.");
puts(" -l, --list Input is a list of file names.");
puts(" -M, --acronym-list <list> Markup acronyms from specified list.");
puts(" -m, --markup Markup acronyms from .acronyms file.");
puts(" -n, --width <#> Minimum spaces after term in pretty printed output.");
puts(" -o, --out <file> Output to <file> instead of stdout.");
puts(" -P, --preformat Remove acronym markup by preformatting it.");
puts(" -p, --pretty Pretty print text/XML output.");
puts(" -q, --quiet Quiet mode.");
puts(" -T, --types <types> Only search for acronyms of these types.");
puts(" -t, --table Format XML output as table.");
puts(" -v, --verbose Verbose output.");
puts(" -X, --select <xpath> Use custom XPath to markup elements.");
puts(" -x, --xml Output XML instead of text.");
puts(" -^, --remove-deleted List acronyms with elements marked as \"delete\" removed.");
puts(" --version Show version information.");
puts(" <dmodule> Data module(s) to process.");
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;
xmlDocPtr doc = NULL;
xmlNodePtr acronyms;
xmlDocPtr defaultChoicesDoc;
bool xmlOut = false;
char *types = NULL;
char *out = strdup("-");
char *markup = NULL;
bool overwrite = false;
bool list = false;
bool delete = false;
bool preformat = false;
const char *sopts = "Ppqn:xDdtT:o:M:miIfl!X:v^h?";
struct option lopts[] = {
{"version" , no_argument , 0, 0},
{"help" , no_argument , 0, 'h'},
{"preformat" , no_argument , 0, 'P'},
{"pretty" , no_argument , 0, 'p'},
{"quiet" , no_argument , 0, 'q'},
{"width" , required_argument, 0, 'n'},
{"xml" , no_argument , 0, 'x'},
{"delete" , no_argument , 0, 'D'},
{"deflist" , no_argument , 0, 'd'},
{"table" , no_argument , 0, 't'},
{"types" , required_argument, 0, 'T'},
{"out" , required_argument, 0, 'o'},
{"markup" , no_argument , 0, 'm'},
{"acronym-list" , required_argument, 0, 'M'},
{"interactive" , no_argument , 0, 'i'},
{"always-ask" , no_argument , 0, 'I'},
{"overwrite" , no_argument , 0, 'f'},
{"list" , no_argument , 0, 'l'},
{"defer-choice" , no_argument , 0, '!'},
{"select" , required_argument, 0, 'X'},
{"verbose" , no_argument , 0, 'v'},
{"remove-deleted", no_argument , 0, '^'},
LIBXML2_PARSE_LONGOPT_DEFS
{0, 0, 0, 0}
};
int loptind = 0;
defaultChoicesDoc = xmlNewDoc(BAD_CAST "1.0");
defaultChoices = xmlNewNode(NULL, BAD_CAST "acronyms");
xmlDocSetRootElement(defaultChoicesDoc, defaultChoices);
while ((i = getopt_long(argc, argv, sopts, lopts, &loptind)) != -1) {
switch (i) {
case 0:
if (strcmp(lopts[loptind].name, "version") == 0) {
show_version();
goto cleanup;
}
LIBXML2_PARSE_LONGOPT_HANDLE(lopts, loptind, optarg)
break;
case 'P':
preformat = true;
break;
case 'p':
prettyPrint = true;
break;
case 'q':
--verbosity;
break;
case 'n':
minimumSpaces = atoi(optarg);
break;
case 'x':
xmlOut = true;
break;
case 'D':
delete = true;
break;
case 'd':
xmlOut = true;
xmlFormat = DEFLIST;
break;
case 't':
xmlOut = true;
xmlFormat = TABLE;
break;
case 'T':
types = strdup(optarg);
break;
case 'o':
free(out);
out = strdup(optarg);
break;
case 'm':
markup = malloc(PATH_MAX);
find_config(markup, DEFAULT_ACRONYMS_FNAME);
break;
case 'M':
markup = strdup(optarg);
break;
case 'i':
interactive = true;
break;
case 'I':
interactive = true;
alwaysAsk = true;
break;
case 'f':
overwrite = true;
break;
case 'l':
list = true;
break;
case '!':
interactive = true;
deferChoice = true;
break;
case 'X':
if (!acro_markup_xpath) {
acro_markup_xpath = xmlStrdup(BAD_CAST optarg);
}
break;
case 'v':
++verbosity;
break;
case '^':
remDelete = true;
break;
case 'h':
case '?':
show_help();
goto cleanup;
}
}
if (!acro_markup_xpath) {
acro_markup_xpath = xmlStrdup(ACRO_MARKUP_XPATH);
}
if (preformat) {
if (optind >= argc) {
if (list) {
preformatAcronymsInList(NULL, out, overwrite);
} else {
preformatAcronymsInFile("-", out);
}
}
for (i = optind; i < argc; ++i) {
if (list) {
preformatAcronymsInList(argv[i], out, overwrite);
} else if (overwrite) {
preformatAcronymsInFile(argv[i], argv[i]);
} else {
preformatAcronymsInFile(argv[i], out);
}
}
} else if (delete) {
if (optind >= argc) {
if (list) {
deleteAcronymsInList(NULL, out, overwrite);
} else {
deleteAcronymsInFile("-", out);
}
}
for (i = optind; i < argc; ++i) {
if (list) {
deleteAcronymsInList(argv[i], out, overwrite);
} else if (overwrite) {
deleteAcronymsInFile(argv[i], argv[i]);
} else {
deleteAcronymsInFile(argv[i], out);
}
}
} else if (markup) {
xmlDocPtr termStylesheetDoc, idStylesheetDoc;
if (!(doc = read_xml_doc(markup))) {
if (verbosity >= NORMAL) {
fprintf(stderr, E_NO_LIST, markup);
}
exit(EXIT_NO_LIST);
}
doc = sortAcronyms(doc);
acronyms = xmlDocGetRootElement(doc);
termStylesheetDoc = read_xml_mem((const char *) stylesheets_term_xsl,
stylesheets_term_xsl_len);
idStylesheetDoc = read_xml_mem((const char *) stylesheets_id_xsl,
stylesheets_id_xsl_len);
termStylesheet = xsltParseStylesheetDoc(termStylesheetDoc);
idStylesheet = xsltParseStylesheetDoc(idStylesheetDoc);
if (optind >= argc) {
if (list) {
markupAcronymsInList(NULL, acronyms, out, overwrite);
} else {
markupAcronymsInFile("-", acronyms, out);
}
}
for (i = optind; i < argc; ++i) {
if (list) {
markupAcronymsInList(argv[i], acronyms, out, overwrite);
} else if (overwrite) {
markupAcronymsInFile(argv[i], acronyms, argv[i]);
} else {
markupAcronymsInFile(argv[i], acronyms, out);
}
}
xsltFreeStylesheet(termStylesheet);
xsltFreeStylesheet(idStylesheet);
} else {
doc = xmlNewDoc(BAD_CAST "1.0");
acronyms = xmlNewNode(NULL, BAD_CAST "acronyms");
xmlDocSetRootElement(doc, acronyms);
if (optind >= argc) {
if (list) {
findAcronymsInList(acronyms, NULL);
} else {
findAcronymsInFile(acronyms, "-");
}
}
for (i = optind; i < argc; ++i) {
if (list) {
findAcronymsInList(acronyms, argv[i]);
} else {
findAcronymsInFile(acronyms, argv[i]);
}
}
doc = removeNonUniqueAcronyms(doc);
if (types)
doc = limitToTypes(doc, types);
if (xmlOut) {
switch (xmlFormat) {
case DEFLIST:
doc = formatXmlAs(doc, stylesheets_list_xsl, stylesheets_list_xsl_len);
break;
case TABLE:
doc = formatXmlAs(doc, stylesheets_table_xsl, stylesheets_table_xsl_len);
break;
default:
break;
}
if (prettyPrint) {
xmlSaveFormatFile(out, doc, 1);
} else {
save_xml_doc(doc, out);
}
} else {
printAcronyms(xmlDocGetRootElement(doc), out);
}
}
cleanup:
free(types);
free(out);
free(markup);
xmlFreeDoc(doc);
xmlFree(acro_markup_xpath);
xmlFreeDoc(defaultChoicesDoc);
xsltCleanupGlobals();
xmlCleanupParser();
return 0;
}
gopher://khzae.net/0/s1000d/s1kd-tools/src/tools/s1kd-acronyms/s1kd-acronyms.c