diff --git a/ChangeLog b/ChangeLog
index 19b6a5c4..e9d762ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Wed Apr 5 20:36:46 CEST 2000 Daniel Veillard
+
+ * xmllint.c: forgot to commit this too ?
+
Wed Apr 5 16:22:44 CEST 2000 Daniel Veillard
* xmlversion.h.in : forgot to commit this previously
diff --git a/xmllint.c b/xmllint.c
new file mode 100644
index 00000000..aa58625c
--- /dev/null
+++ b/xmllint.c
@@ -0,0 +1,620 @@
+/*
+ * xmllint.c : a small tester program for XML input.
+ *
+ * See Copyright for the status of this software.
+ *
+ * Daniel.Veillard@w3.org
+ */
+
+#ifdef WIN32
+#include "win32config.h"
+#else
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+#include
+
+#ifdef HAVE_SYS_TYPES_H
+#include
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include
+#endif
+#ifdef HAVE_FCNTL_H
+#include
+#endif
+#ifdef HAVE_UNISTD_H
+#include
+#endif
+#ifdef HAVE_STDLIB_H
+#include
+#endif
+#ifdef HAVE_LIBREADLINE
+#include
+#ifdef HAVE_LIBHISTORY
+#include
+#endif
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef LIBXML_DEBUG_ENABLED
+static int debug = 0;
+static int shell = 0;
+static int debugent = 0;
+#endif
+static int copy = 0;
+static int recovery = 0;
+static int noent = 0;
+static int noout = 0;
+static int nowrap = 0;
+static int valid = 0;
+static int postvalid = 0;
+static int repeat = 0;
+static int insert = 0;
+static int compress = 0;
+static int html = 0;
+static int htmlout = 0;
+static int push = 0;
+static int noblanks = 0;
+
+extern int xmlDoValidityCheckingDefaultValue;
+extern int xmlGetWarningsDefaultValue;
+
+/************************************************************************
+ * *
+ * HTML ouput *
+ * *
+ ************************************************************************/
+char buffer[50000];
+
+void
+xmlHTMLEncodeSend(void) {
+ char *result;
+
+ result = (char *) xmlEncodeEntitiesReentrant(NULL, BAD_CAST buffer);
+ if (result) {
+ fprintf(stderr, "%s", result);
+ xmlFree(result);
+ }
+ buffer[0] = 0;
+}
+
+/**
+ * xmlHTMLPrintFileInfo:
+ * @input: an xmlParserInputPtr input
+ *
+ * Displays the associated file and line informations for the current input
+ */
+
+void
+xmlHTMLPrintFileInfo(xmlParserInputPtr input) {
+ fprintf(stderr, "");
+ if (input != NULL) {
+ if (input->filename) {
+ sprintf(&buffer[strlen(buffer)], "%s:%d: ", input->filename,
+ input->line);
+ } else {
+ sprintf(&buffer[strlen(buffer)], "Entity: line %d: ", input->line);
+ }
+ }
+ xmlHTMLEncodeSend();
+}
+
+/**
+ * xmlHTMLPrintFileContext:
+ * @input: an xmlParserInputPtr input
+ *
+ * Displays current context within the input content for error tracking
+ */
+
+void
+xmlHTMLPrintFileContext(xmlParserInputPtr input) {
+ const xmlChar *cur, *base;
+ int n;
+
+ if (input == NULL) return;
+ fprintf(stderr, "
\n");
+ cur = input->cur;
+ base = input->base;
+ while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
+ cur--;
+ }
+ n = 0;
+ while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
+ cur--;
+ if ((*cur == '\n') || (*cur == '\r')) cur++;
+ base = cur;
+ n = 0;
+ while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
+ sprintf(&buffer[strlen(buffer)], "%c", (unsigned char) *cur++);
+ n++;
+ }
+ sprintf(&buffer[strlen(buffer)], "\n");
+ cur = input->cur;
+ while ((*cur == '\n') || (*cur == '\r'))
+ cur--;
+ n = 0;
+ while ((cur != base) && (n++ < 80)) {
+ sprintf(&buffer[strlen(buffer)], " ");
+ base++;
+ }
+ sprintf(&buffer[strlen(buffer)],"^\n");
+ xmlHTMLEncodeSend();
+ fprintf(stderr, "
");
+}
+
+/**
+ * xmlHTMLError:
+ * @ctx: an XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format an error messages, gives file, line, position and
+ * extra parameters.
+ */
+void
+xmlHTMLError(void *ctx, const char *msg, ...)
+{
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ xmlParserInputPtr input;
+ xmlParserInputPtr cur = NULL;
+ va_list args;
+
+ buffer[0] = 0;
+ input = ctxt->input;
+ if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
+ cur = input;
+ input = ctxt->inputTab[ctxt->inputNr - 2];
+ }
+
+ xmlHTMLPrintFileInfo(input);
+
+ fprintf(stderr, "error: ");
+ va_start(args, msg);
+ vsprintf(&buffer[strlen(buffer)], msg, args);
+ va_end(args);
+ xmlHTMLEncodeSend();
+ fprintf(stderr, "
\n");
+
+ xmlHTMLPrintFileContext(input);
+ xmlHTMLEncodeSend();
+}
+
+/**
+ * xmlHTMLWarning:
+ * @ctx: an XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format a warning messages, gives file, line, position and
+ * extra parameters.
+ */
+void
+xmlHTMLWarning(void *ctx, const char *msg, ...)
+{
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ xmlParserInputPtr input;
+ xmlParserInputPtr cur = NULL;
+ va_list args;
+
+ buffer[0] = 0;
+ input = ctxt->input;
+ if ((input != NULL) && (input->filename == NULL) && (ctxt->inputNr > 1)) {
+ cur = input;
+ input = ctxt->inputTab[ctxt->inputNr - 2];
+ }
+
+
+ xmlHTMLPrintFileInfo(input);
+
+ fprintf(stderr, "warning: ");
+ va_start(args, msg);
+ vsprintf(&buffer[strlen(buffer)], msg, args);
+ va_end(args);
+ xmlHTMLEncodeSend();
+ fprintf(stderr, "\n");
+
+ xmlHTMLPrintFileContext(input);
+ xmlHTMLEncodeSend();
+}
+
+/**
+ * xmlHTMLValidityError:
+ * @ctx: an XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format an validity error messages, gives file,
+ * line, position and extra parameters.
+ */
+void
+xmlHTMLValidityError(void *ctx, const char *msg, ...)
+{
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ xmlParserInputPtr input;
+ va_list args;
+
+ buffer[0] = 0;
+ input = ctxt->input;
+ if ((input->filename == NULL) && (ctxt->inputNr > 1))
+ input = ctxt->inputTab[ctxt->inputNr - 2];
+
+ xmlHTMLPrintFileInfo(input);
+
+ fprintf(stderr, "validity error: ");
+ va_start(args, msg);
+ vsprintf(&buffer[strlen(buffer)], msg, args);
+ va_end(args);
+ xmlHTMLEncodeSend();
+ fprintf(stderr, "\n");
+
+ xmlHTMLPrintFileContext(input);
+ xmlHTMLEncodeSend();
+}
+
+/**
+ * xmlHTMLValidityWarning:
+ * @ctx: an XML parser context
+ * @msg: the message to display/transmit
+ * @...: extra parameters for the message display
+ *
+ * Display and format a validity warning messages, gives file, line,
+ * position and extra parameters.
+ */
+void
+xmlHTMLValidityWarning(void *ctx, const char *msg, ...)
+{
+ xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx;
+ xmlParserInputPtr input;
+ va_list args;
+
+ buffer[0] = 0;
+ input = ctxt->input;
+ if ((input->filename == NULL) && (ctxt->inputNr > 1))
+ input = ctxt->inputTab[ctxt->inputNr - 2];
+
+ xmlHTMLPrintFileInfo(input);
+
+ fprintf(stderr, "validity warning: ");
+ va_start(args, msg);
+ vsprintf(&buffer[strlen(buffer)], msg, args);
+ va_end(args);
+ xmlHTMLEncodeSend();
+ fprintf(stderr, "\n");
+
+ xmlHTMLPrintFileContext(input);
+ xmlHTMLEncodeSend();
+}
+
+/************************************************************************
+ * *
+ * 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.
+ */
+char *
+xmlShellReadline(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
+}
+
+/************************************************************************
+ * *
+ * Test processing *
+ * *
+ ************************************************************************/
+void parseAndPrintFile(char *filename) {
+ xmlDocPtr doc = NULL, tmp;
+
+#ifdef LIBXML_HTML_ENABLED
+ if (html) {
+ doc = htmlParseFile(filename, NULL);
+ } else {
+#endif /* LIBXML_HTML_ENABLED */
+ /*
+ * build an XML tree from a string;
+ */
+ if (push) {
+ FILE *f;
+
+ f = fopen(filename, "r");
+ if (f != NULL) {
+ int res, size = 3;
+ char chars[1024];
+ xmlParserCtxtPtr ctxt;
+
+ if (repeat)
+ size = 1024;
+ res = fread(chars, 1, 4, f);
+ if (res > 0) {
+ ctxt = xmlCreatePushParserCtxt(NULL, NULL,
+ chars, res, filename);
+ while ((res = fread(chars, 1, size, f)) > 0) {
+ xmlParseChunk(ctxt, chars, res, 0);
+ }
+ xmlParseChunk(ctxt, chars, 0, 1);
+ doc = ctxt->myDoc;
+ xmlFreeParserCtxt(ctxt);
+ }
+ }
+ } else if (recovery) {
+ doc = xmlRecoverFile(filename);
+ } else if (htmlout) {
+ int ret;
+ xmlParserCtxtPtr ctxt;
+ xmlSAXHandler silent, *old;
+
+ ctxt = xmlCreateFileParserCtxt(filename);
+ memcpy(&silent, ctxt->sax, sizeof(silent));
+ old = ctxt->sax;
+ silent.error = xmlHTMLError;
+ if (xmlGetWarningsDefaultValue)
+ silent.warning = xmlHTMLWarning;
+ else
+ silent.warning = NULL;
+ silent.fatalError = xmlHTMLError;
+ ctxt->sax = &silent;
+ ctxt->vctxt.error = xmlHTMLValidityError;
+ if (xmlGetWarningsDefaultValue)
+ ctxt->vctxt.warning = xmlHTMLValidityWarning;
+ else
+ ctxt->vctxt.warning = NULL;
+
+ xmlParseDocument(ctxt);
+
+ ret = ctxt->wellFormed;
+ doc = ctxt->myDoc;
+ ctxt->sax = old;
+ xmlFreeParserCtxt(ctxt);
+ if (!ret) {
+ xmlFreeDoc(doc);
+ doc = NULL;
+ }
+ } else
+ doc = xmlParseFile(filename);
+#ifdef LIBXML_HTML_ENABLED
+ }
+#endif
+
+#ifdef LIBXML_DEBUG_ENABLED
+ /*
+ * shell interraction
+ */
+ if (shell)
+ xmlShell(doc, filename, xmlShellReadline, stdout);
+#endif
+
+ /*
+ * test intermediate copy if needed.
+ */
+ if (copy) {
+ tmp = doc;
+ doc = xmlCopyDoc(doc, 1);
+ xmlFreeDoc(tmp);
+ }
+
+ if ((insert) && (!html)) {
+ const xmlChar* list[256];
+ int nb, i;
+ xmlNodePtr node;
+
+ if (doc->children != NULL) {
+ node = doc->children;
+ while ((node != NULL) && (node->last == NULL)) node = node->next;
+ if (node != NULL) {
+ nb = xmlValidGetValidElements(node->last, NULL, list, 256);
+ if (nb < 0) {
+ printf("could not get valid list of elements\n");
+ } else if (nb == 0) {
+ printf("No element can be indersted under root\n");
+ } else {
+ printf("%d element types can be indersted under root:\n",
+ nb);
+ for (i = 0;i < nb;i++) {
+ printf("%s\n", list[i]);
+ }
+ }
+ }
+ }
+ }else if (noout == 0) {
+ /*
+ * print it.
+ */
+#ifdef LIBXML_DEBUG_ENABLED
+ if (!debug) {
+#endif
+ if (compress)
+ xmlSaveFile("-", doc);
+ else
+ xmlDocDump(stdout, doc);
+#ifdef LIBXML_DEBUG_ENABLED
+ } else
+ xmlDebugDumpDocument(stdout, doc);
+#endif
+ }
+
+ /*
+ * A posteriori validation test
+ */
+ if (postvalid) {
+ xmlValidCtxt cvp;
+ cvp.userData = (void *) stderr; cvp.error = (xmlValidityErrorFunc) fprintf; cvp.warning = (xmlValidityWarningFunc) fprintf;
+ xmlValidateDocument(&cvp, doc);
+ }
+
+#ifdef LIBXML_DEBUG_ENABLED
+ if ((debugent) && (!html))
+ xmlDebugDumpEntities(stdout, doc);
+#endif
+
+ /*
+ * free it.
+ */
+ xmlFreeDoc(doc);
+}
+
+int main(int argc, char **argv) {
+ int i, count;
+ int files = 0;
+
+ for (i = 1; i < argc ; i++) {
+#ifdef LIBXML_DEBUG_ENABLED
+ if ((!strcmp(argv[i], "-debug")) || (!strcmp(argv[i], "--debug")))
+ debug++;
+ else if ((!strcmp(argv[i], "-debugent")) || (!strcmp(argv[i], "--debugent")))
+ debugent++;
+ else if ((!strcmp(argv[i], "-shell")) ||
+ (!strcmp(argv[i], "--shell"))) {
+ shell++;
+ noout = 1;
+ } else
+#endif
+ if ((!strcmp(argv[i], "-copy")) || (!strcmp(argv[i], "--copy")))
+ copy++;
+ else if ((!strcmp(argv[i], "-recover")) ||
+ (!strcmp(argv[i], "--recover")))
+ recovery++;
+ else if ((!strcmp(argv[i], "-noent")) ||
+ (!strcmp(argv[i], "--noent")))
+ noent++;
+ else if ((!strcmp(argv[i], "-noout")) ||
+ (!strcmp(argv[i], "--noout")))
+ noout++;
+ else if ((!strcmp(argv[i], "-htmlout")) ||
+ (!strcmp(argv[i], "--htmlout")))
+ htmlout++;
+#ifdef LIBXML_HTML_ENABLED
+ else if ((!strcmp(argv[i], "-html")) ||
+ (!strcmp(argv[i], "--html"))) {
+ html++;
+ }
+#endif /* LIBXML_HTML_ENABLED */
+ else if ((!strcmp(argv[i], "-nowrap")) ||
+ (!strcmp(argv[i], "--nowrap")))
+ nowrap++;
+ else if ((!strcmp(argv[i], "-valid")) ||
+ (!strcmp(argv[i], "--valid")))
+ valid++;
+ else if ((!strcmp(argv[i], "-postvalid")) ||
+ (!strcmp(argv[i], "--postvalid")))
+ postvalid++;
+ else if ((!strcmp(argv[i], "-insert")) ||
+ (!strcmp(argv[i], "--insert")))
+ insert++;
+ else if ((!strcmp(argv[i], "-repeat")) ||
+ (!strcmp(argv[i], "--repeat")))
+ repeat++;
+ else if ((!strcmp(argv[i], "-push")) ||
+ (!strcmp(argv[i], "--push")))
+ push++;
+ else if ((!strcmp(argv[i], "-compress")) ||
+ (!strcmp(argv[i], "--compress"))) {
+ compress++;
+ xmlSetCompressMode(9);
+ }
+ else if ((!strcmp(argv[i], "-nowarning")) ||
+ (!strcmp(argv[i], "--nowarning"))) {
+ xmlGetWarningsDefaultValue = 0;
+ }
+ else if ((!strcmp(argv[i], "-noblanks")) ||
+ (!strcmp(argv[i], "--noblanks"))) {
+ noblanks++;
+ xmlKeepBlanksDefault(0);
+ }
+ }
+ if (noent != 0) xmlSubstituteEntitiesDefault(1);
+ if (valid != 0) xmlDoValidityCheckingDefaultValue = 1;
+ if ((htmlout) && (!nowrap)) {
+ fprintf(stderr,
+ "\n");
+ fprintf(stderr,
+ "%s output\n",
+ argv[0]);
+ fprintf(stderr,
+ "%s output
\n",
+ argv[0]);
+ }
+ for (i = 1; i < argc ; i++) {
+ if (argv[i][0] != '-') {
+ if (repeat) {
+ for (count = 0;count < 100 * repeat;count++)
+ parseAndPrintFile(argv[i]);
+ } else
+ parseAndPrintFile(argv[i]);
+ files ++;
+ }
+ }
+ if ((htmlout) && (!nowrap)) {
+ fprintf(stderr, "\n");
+ }
+ if (files == 0) {
+ printf("Usage : %s [--debug] [--debugent] [--copy] [--recover] [--noent] [--noout] [--valid] [--repeat] XMLfiles ...\n",
+ argv[0]);
+ printf("\tParse the XML files and output the result of the parsing\n");
+#ifdef LIBXML_DEBUG_ENABLED
+ printf("\t--debug : dump a debug tree of the in-memory document\n");
+ printf("\t--shell : run a navigating shell\n");
+ printf("\t--debugent : debug the entities defined in the document\n");
+#endif
+ printf("\t--copy : used to test the internal copy implementation\n");
+ printf("\t--recover : output what was parsable on broken XML documents\n");
+ printf("\t--noent : substitute entity references by their value\n");
+ printf("\t--noout : don't output the result tree\n");
+ printf("\t--htmlout : output results as HTML\n");
+ printf("\t--nowarp : do not put HTML doc wrapper\n");
+ printf("\t--valid : validate the document in addition to std well-formed check\n");
+ printf("\t--postvalid : do a posteriori validation, i.e after parsing\n");
+ printf("\t--repeat : repeat 100 times, for timing or profiling\n");
+ printf("\t--insert : ad-hoc test for valid insertions\n");
+ printf("\t--compress : turn on gzip compression of output\n");
+#ifdef LIBXML_HTML_ENABLED
+ printf("\t--html : use the HTML parser\n");
+#endif
+ printf("\t--push : use the push mode of the parser\n");
+ printf("\t--nowarning : do not emit warnings from parser/validator\n");
+ printf("\t--noblanks : drop (ignorable?) blanks spaces\n");
+ }
+ xmlCleanupParser();
+ xmlMemoryDump();
+
+ return(0);
+}