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;
+}