#include #include #include #include #include #include #include #include #include #include #include #include #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 ] [-T ] [...]"); puts(" " PROG_NAME " [-flqv] [-i|-I|-!] [-m|-M ] [-o ] [-X ] [...]"); puts(" " PROG_NAME " [-D|-P] [-flqv] [-o ] [...]"); 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 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 Output to 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 Only search for acronyms of these types."); puts(" -t, --table Format XML output as table."); puts(" -v, --verbose Verbose output."); puts(" -X, --select 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(" 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; }