renaming testCatalog as xmlcatalog, making it an installed app adding a
* Makefile.am xmlcatalog.c libxml.spec.in: renaming
testCatalog as xmlcatalog, making it an installed app
adding a shell, and preparing it to be a /etc/xml/catalog
management tool, though not ready yet
* catalog.c include/libxml/catalog.h: adding support for
XML Catalogs http://www.oasis-open.org/committees/entity/
not finished, there is some interesting tradeoffs and a
few open questions left.
Daniel
diff --git a/xmlcatalog.c b/xmlcatalog.c
new file mode 100644
index 0000000..0063bca
--- /dev/null
+++ b/xmlcatalog.c
@@ -0,0 +1,216 @@
+/*
+ * xmlcatalog.c : a small utility program to handle XML catalogs
+ *
+ * See Copyright for the status of this software.
+ *
+ * daniel@veillard.com
+ */
+
+#include "libxml.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include <libxml/xmlmemory.h>
+#include <libxml/uri.h>
+#include <libxml/catalog.h>
+#include <libxml/parser.h>
+
+static int shell = 0;
+static int noout = 0;
+static int verbose = 0;
+
+#ifdef LIBXML_CATALOG_ENABLED
+/************************************************************************
+ * *
+ * Shell Interface *
+ * *
+ ************************************************************************/
+/**
+ * xmlShellReadline:
+ * @prompt: the prompt value
+ *
+ * Read a string
+ *
+ * Returns a pointer to it or NULL on EOF the caller is expected to
+ * free the returned string.
+ */
+static char *
+xmlShellReadline(const char *prompt) {
+#ifdef HAVE_LIBREADLINE
+ char *line_read;
+
+ /* Get a line from the user. */
+ line_read = readline (prompt);
+
+ /* If the line has any text in it, save it on the history. */
+ if (line_read && *line_read)
+ add_history (line_read);
+
+ return (line_read);
+#else
+ char line_read[501];
+
+ if (prompt != NULL)
+ fprintf(stdout, "%s", prompt);
+ if (!fgets(line_read, 500, stdin))
+ return(NULL);
+ line_read[500] = 0;
+ return(strdup(line_read));
+#endif
+}
+
+
+static void usershell(void) {
+ char *cmdline = NULL, *cur;
+ int nbargs;
+ char command[100];
+ char arg[400];
+ int i;
+ const xmlChar *answer;
+
+ while (1) {
+ cmdline = xmlShellReadline("> ");
+ if (cmdline == NULL)
+ return;
+
+ /*
+ * Parse the command itself
+ */
+ cur = cmdline;
+ nbargs = 0;
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
+ i = 0;
+ while ((*cur != ' ') && (*cur != '\t') &&
+ (*cur != '\n') && (*cur != '\r')) {
+ if (*cur == 0)
+ break;
+ command[i++] = *cur++;
+ }
+ command[i] = 0;
+ if (i == 0) continue;
+ nbargs++;
+
+ /*
+ * Parse the argument
+ */
+ while ((*cur == ' ') || (*cur == '\t')) cur++;
+ i = 0;
+ while ((*cur != '\n') && (*cur != '\r') && (*cur != 0)) {
+ if (*cur == 0)
+ break;
+ arg[i++] = *cur++;
+ }
+ arg[i] = 0;
+ if (i != 0)
+ nbargs++;
+
+ /*
+ * start interpreting the command
+ */
+ if (!strcmp(command, "exit"))
+ break;
+ if (!strcmp(command, "quit"))
+ break;
+ if (!strcmp(command, "bye"))
+ break;
+ if (!strcmp(command, "public")) {
+ answer = xmlCatalogGetPublic((const xmlChar *) arg);
+ if (answer == NULL) {
+ printf("No entry for PUBLIC %s\n", arg);
+ } else {
+ printf("%s\n", answer);
+ }
+ } else if (!strcmp(command, "system")) {
+ answer = xmlCatalogGetSystem((const xmlChar *) arg);
+ if (answer == NULL) {
+ printf("No entry for SYSTEM %s\n", arg);
+ } else {
+ printf("%s\n", answer);
+ }
+ } else if (!strcmp(command, "dump")) {
+ xmlCatalogDump(stdout);
+ } else {
+ if (strcmp(command, "help")) {
+ printf("Unrecognized command %s\n", command);
+ }
+ printf("Commands available:\n");
+ printf("\tpublic PublicID: make a PUBLIC identifier lookup\n");
+ printf("\tsystem SystemID: make a SYSTEM identifier lookup\n");
+ printf("\tdump: print the current catalog state\n");
+ printf("\texit: quit the shell\n");
+ }
+ free(cmdline); /* not xmlFree here ! */
+ }
+}
+
+/************************************************************************
+ * *
+ * Main *
+ * *
+ ************************************************************************/
+static void usage(const char *name) {
+ printf("Usage : %s [options] catalogfile ...\n", name);
+ printf("\tParse the catalog file(s) and output the result of the parsing\n");
+ printf("\t--shell : run a shell allowing interactive queries\n");
+ printf("\t-v --verbose : provide debug informations\n");
+}
+int main(int argc, char **argv) {
+ int i;
+
+ if (argc <= 1) {
+ usage(argv[0]);
+ return(1);
+ }
+
+ LIBXML_TEST_VERSION
+ for (i = 1; i < argc ; i++) {
+ if (!strcmp(argv[i], "-"))
+ break;
+
+ if (argv[i][0] != '-')
+ continue;
+ if ((!strcmp(argv[i], "-verbose")) ||
+ (!strcmp(argv[i], "-v")) ||
+ (!strcmp(argv[i], "--verbose"))) {
+ verbose++;
+ xmlCatalogSetDebug(verbose);
+ } else if ((!strcmp(argv[i], "-shell")) ||
+ (!strcmp(argv[i], "--shell"))) {
+ shell++;
+ noout = 1;
+ } else {
+ fprintf(stderr, "Unknown option %s\n", argv[i]);
+ usage(argv[0]);
+ return(1);
+ }
+ }
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-')
+ continue;
+ xmlLoadCatalog(argv[i]);
+ }
+
+ if (shell) {
+ usershell();
+ }
+ if (!noout) {
+ xmlCatalogDump(stdout);
+ }
+
+ /*
+ * Cleanup and check for memory leaks
+ */
+ xmlCatalogCleanup();
+ xmlCleanupParser();
+ xmlMemoryDump();
+ return(0);
+}
+#else
+int main(int argc, char **argv) {
+ fprintf(stderr, "libxml was not compiled with catalog support\n");
+ return(1);
+}
+#endif