Release 0.2, 80% rewrite, nothing left intact ... Daniel
diff --git a/SAX.c b/SAX.c
new file mode 100644
index 0000000..17a8277
--- /dev/null
+++ b/SAX.c
@@ -0,0 +1,223 @@
+/*
+ * SAX.c : Default SAX handler to build a tree.
+ */
+
+#include <stdio.h>
+#include <malloc.h>
+#include "tree.h"
+#include "parser.h"
+#include "error.h"
+
+/* #define DEBUG_SAX */
+
+/*
+ * Return the public ID e.g. "-//SGMLSOURCE//DTD DEMO//EN"
+ */
+const CHAR *getPublicId(xmlParserCtxtPtr ctxt) {
+ return(NULL);
+}
+
+/*
+ * Return the system ID, basically URI or filename e.g.
+ * http://www.sgmlsource.com/dtds/memo.dtd
+ */
+const CHAR *getSystemId(xmlParserCtxtPtr ctxt) {
+ return(ctxt->input->filename);
+}
+
+/*
+ * Return the line number of the current parsing point.
+ */
+int getLineNumber(xmlParserCtxtPtr ctxt) {
+ return(ctxt->input->line);
+}
+/*
+ * Return the column number of the current parsing point.
+ */
+int getColumnNumber(xmlParserCtxtPtr ctxt) {
+ return(ctxt->input->col);
+}
+
+/*
+ * The default SAX Locator.
+ */
+
+xmlSAXLocator xmlDefaultSAXLocator = {
+ getPublicId, getSystemId, getLineNumber, getColumnNumber
+};
+
+/*
+ * Special entity resolver, better left to the parser, it has
+ * more context than the application layer.
+ */
+xmlParserInputPtr resolveEntity(xmlParserCtxtPtr ctxt,
+ const CHAR *publicId, const CHAR *systemId) {
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.resolveEntity(%s, %s)\n", publicId, systemId);
+#endif
+ return(NULL);
+}
+
+/*
+ * What to do when a notation declaration has been parsed.
+ * TODO Not handled currently.
+ */
+void notationDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR *publicId, const CHAR *systemId) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.notationDecl(%s, %s, %s)\n", name, publicId, systemId);
+#endif
+}
+
+/*
+ * What to do when an unparsed entity declaration is parsed
+ * TODO Create an Entity node.
+ */
+void unparsedEntityDecl(xmlParserCtxtPtr ctxt, const CHAR *name,
+ const CHAR *publicId, const CHAR *systemId,
+ const CHAR *notationName) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.unparsedEntityDecl(%s, %s, %s, %s)\n",
+ name, publicId, systemId, notationName);
+#endif
+}
+
+/*
+ * Receive the document locator at startup, actually xmlDefaultSAXLocator
+ * Everything is available on the context, so this is useless in our case.
+ */
+void setDocumentLocator(xmlParserCtxtPtr ctxt, xmlSAXLocatorPtr loc) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.setDocumentLocator()\n");
+#endif
+}
+
+/*
+ * called when the document start being processed.
+ */
+void startDocument(xmlParserCtxtPtr ctxt) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.startDocument()\n");
+#endif
+}
+
+/*
+ * called when the document end has been detected.
+ */
+void endDocument(xmlParserCtxtPtr ctxt) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.endDocument()\n");
+#endif
+}
+
+/*
+ * called when an opening tag has been processed.
+ * TODO We currently have a small pblm with the arguments ...
+ */
+void startElement(xmlParserCtxtPtr ctxt, const CHAR *name) {
+ xmlNodePtr parent;
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.startElement(%s)\n", name);
+#endif
+ if (ctxt->nodeNr < 2) return;
+ parent = ctxt->nodeTab[ctxt->nodeNr - 2];
+ if (parent != NULL)
+ xmlAddChild(parent, ctxt->node);
+
+}
+
+/*
+ * called when the end of an element has been detected.
+ */
+void endElement(xmlParserCtxtPtr ctxt, const CHAR *name) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.endElement(%s)\n", name);
+#endif
+}
+
+/*
+ * receiving some chars from the parser.
+ * Question: how much at a time ???
+ */
+void characters(xmlParserCtxtPtr ctxt, const CHAR *ch,
+ int start, int len) {
+ xmlNodePtr lastChild;
+
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.characters(%.30s, %d, %d)\n", ch, start, len);
+#endif
+ /*
+ * Handle the data if any. If there is no child
+ * add it as content, otherwise if the last child is text,
+ * concatenate it, else create a new node of type text.
+ */
+
+ lastChild = xmlGetLastChild(ctxt->node);
+ if (lastChild == NULL)
+ xmlNodeAddContentLen(ctxt->node, &ch[start], len);
+ else {
+ if (xmlNodeIsText(lastChild))
+ xmlTextConcat(lastChild, &ch[start], len);
+ else {
+ lastChild = xmlNewTextLen(&ch[start], len);
+ xmlAddChild(ctxt->node, lastChild);
+ }
+ }
+}
+
+/*
+ * receiving some ignorable whitespaces from the parser.
+ * Question: how much at a time ???
+ */
+void ignorableWhitespace(xmlParserCtxtPtr ctxt, const CHAR *ch,
+ int start, int len) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.ignorableWhitespace(%.30s, %d, %d)\n", ch, start, len);
+#endif
+}
+
+/*
+ * A processing instruction has beem parsed.
+ */
+void processingInstruction(xmlParserCtxtPtr ctxt, const CHAR *target,
+ const CHAR *data) {
+#ifdef DEBUG_SAX
+ fprintf(stderr, "SAX.processingInstruction(%s, %s)\n", target, data);
+#endif
+}
+
+xmlSAXHandler xmlDefaultSAXHandler = {
+ resolveEntity,
+ notationDecl,
+ unparsedEntityDecl,
+ setDocumentLocator,
+ startDocument,
+ endDocument,
+ startElement,
+ endElement,
+ characters,
+ ignorableWhitespace,
+ processingInstruction,
+ xmlParserWarning,
+ xmlParserError,
+ xmlParserError,
+};
+
+void xmlDefaultSAXHandlerInit(void) {
+ xmlDefaultSAXHandler.resolveEntity = resolveEntity;
+ xmlDefaultSAXHandler.notationDecl = notationDecl;
+ xmlDefaultSAXHandler.unparsedEntityDecl = unparsedEntityDecl;
+ xmlDefaultSAXHandler.setDocumentLocator = setDocumentLocator;
+ xmlDefaultSAXHandler.startDocument = startDocument;
+ xmlDefaultSAXHandler.endDocument = endDocument;
+ xmlDefaultSAXHandler.startElement = startElement;
+ xmlDefaultSAXHandler.endElement = endElement;
+ xmlDefaultSAXHandler.characters = characters;
+ xmlDefaultSAXHandler.ignorableWhitespace = ignorableWhitespace;
+ xmlDefaultSAXHandler.processingInstruction = processingInstruction;
+ xmlDefaultSAXHandler.warning = xmlParserWarning;
+ xmlDefaultSAXHandler.error = xmlParserError;
+ xmlDefaultSAXHandler.fatalError = xmlParserError;
+}