Just to collect it all together, I attach a patch against 0.41

The patch makes the following changes:

1. namespace declarations are not output more often than necessary.
    (vanilla 0.41 will repeat declarations to the point of producing
    ill-formed output)

2. the current() function is implemented.

3. substring() behaves correctly if it goes beyond the end of the
    string.

4. if the output method is "text", including a stylesheet with a
    DTD will not cause an error.


 .robin.

-- 
Are we not drawn onward, we few, drawn onward to new era?
diff -ur Sablot-0.41/Sablot/engine/context.cpp 
Sablot-0.41-patched/Sablot/engine/context.cpp
--- Sablot-0.41/Sablot/engine/context.cpp       Tue Jul 11 15:23:28 2000
+++ Sablot-0.41-patched/Sablot/engine/context.cpp       Tue Jul 11 16:56:55 2000
@@ -67,6 +67,7 @@
 Context::Context()
 {
     array = new CList;
+    currentNode = NULL;
     position = -1;
 }
 
@@ -85,6 +86,19 @@
         return NULL;
 };
 
+Vertex *Context::getCurrentNode() const
+{
+    if (currentNode)
+        return currentNode;
+    else
+        return current();
+}
+
+void Context::setCurrentNode(Vertex * v)
+{
+    currentNode = v;
+}
+
 void Context::reset()
 {
     if (!array -> number())
@@ -152,6 +166,7 @@
 {
     Context *newc = new Context;
     delete NZ(newc -> array);
+    newc -> currentNode = currentNode;
     newc -> array = array;
     array -> incRefCount();
     newc -> reset();
@@ -174,7 +189,8 @@
     {
         vstamp = (v = (*array)[i]) -> stamp;
         wstamp = (w = (*(other -> array))[j]) -> stamp;
-        if (vstamp == wstamp)
+        if (v == w) //XXXX wrong! need consistent document ordering
+//        if (vstamp == wstamp)
         {
             j++;
             continue;
diff -ur Sablot-0.41/Sablot/engine/context.h 
Sablot-0.41-patched/Sablot/engine/context.h
--- Sablot-0.41/Sablot/engine/context.h Tue Jul 11 15:23:28 2000
+++ Sablot-0.41-patched/Sablot/engine/context.h Tue Jul 11 16:56:55 2000
@@ -68,6 +68,10 @@
     ~Context();
     Vertex 
         *current() const;
+    Vertex
+        *getCurrentNode() const;
+    void
+        setCurrentNode(Vertex *);
     void    
         reset();
     Bool 
@@ -99,6 +103,8 @@
 protected:
     CList 
         *array;
+    Vertex
+        *currentNode;
 };
 
 #endif  //ifndef ContextHIncl
diff -ur Sablot-0.41/Sablot/engine/expr.cpp Sablot-0.41-patched/Sablot/engine/expr.cpp
--- Sablot-0.41/Sablot/engine/expr.cpp  Tue Jul 11 15:23:28 2000
+++ Sablot-0.41-patched/Sablot/engine/expr.cpp  Tue Jul 11 16:56:55 2000
@@ -868,7 +868,9 @@
     Vertex 
         *baseV = (*c)[baseIndex],
         *v;
+    Vertex *currentNode = c->getCurrentNode();
     c = new Context;
+    c->setCurrentNode(currentNode);
 
     switch(ax)
     {
@@ -2325,6 +2327,7 @@
     assert(source);
     int len = strlen(source);
     if (from < 0) from = 0;
+    if (to >= len) to = len-1;
     if ((from >= len) || ((to != -1) && (from > to)))
         s = "";
     else
@@ -2662,6 +2665,10 @@
             DStr location;
             Tree *newtree;
             Context *newc = new Context;
+
+            // Current node doesn't change
+            newc->setCurrentNode (c->getCurrentNode());
+
             if (atoms[0] -> type == EX_NODESET)
             {
                 const Context& ctxt = atoms[0] -> tonodesetRef();
@@ -2731,6 +2738,14 @@
             else
                 retxpr.setAtom(Str(""));
         }; break;
+
+    case EXFF_CURRENT:
+        {
+            Context *newc = new Context;
+            newc -> set (c -> getCurrentNode());
+            retxpr.setAtom (newc);
+        }; break;
+
     default:
         Err1(ET_FUNC_NOT_SUPPORTED, getFuncName(functor));
     }
@@ -2746,7 +2761,8 @@
         c = new Context;
         return OK;
     };
-    E( args[0] -> createContext(myctxt = c, baseNdx) );
+    ( myctxt = c ) -> setCurrentNode ( c->getCurrentNode() );
+    E( args[0] -> createContext(myctxt, baseNdx) );
     E( createLPContextSum(1, c = myctxt) );
     delete myctxt;
     return OK;
@@ -2809,7 +2825,9 @@
             Expression *deref = proc -> getVarBinding(*pName);
             if (!deref)
                 Err(ET_VARIABLE_NOT_FOUND);
+            Vertex * current_node = c -> getCurrentNode();
             E( deref -> createContext(c, baseNdx) );
+            c->setCurrentNode (current_node);
         };
         break;
     case EXF_ATOM:
diff -ur Sablot-0.41/Sablot/engine/output.cpp 
Sablot-0.41-patched/Sablot/engine/output.cpp
--- Sablot-0.41/Sablot/engine/output.cpp        Tue Jul 11 15:23:28 2000
+++ Sablot-0.41-patched/Sablot/engine/output.cpp        Tue Jul 11 17:08:11 2000
@@ -278,7 +278,8 @@
 }
 
 eFlag PhysicalOutputLayerObj::outputElementStart(const Str& name,
-    const StrStrList& namespaces, const QNameStrList& atts, Bool isEmpty)
+    const StrStrList& namespaces, const int namespace_index,
+    const QNameStrList& atts, Bool isEmpty)
 {
     // begin output of start tag: output element name
 
@@ -289,7 +290,7 @@
 
     int i;
     const Str* prefix;
-    for (i = 0; i < namespaces.number(); i++)
+    for (i = namespace_index; i < namespaces.number(); i++)
     {
         sendLit(" xmlns");
         prefix = &(namespaces[i] -> key);
@@ -849,7 +850,10 @@
                 E( reportXMLDeclIfMust() );
                 E( reportFront() );
             };
-            E( reportDTDIfMust( name ) );
+            // If this is an included stylesheet, output method cd be TEXT here
+            if (method == OUTPUT_XML || method == OUTPUT_HTML) {
+                E( reportDTDIfMust( name ) );
+            }
         };
     }
     switch(state)
@@ -1013,7 +1017,9 @@
 eFlag OutputterObj::eventNamespace(const Str& prefix, const Str& uri)
 {
     assert(state == STATE_IN_MARKUP);
-    currNamespaces.appendConstruct(prefix, uri);
+    Str * existing_namespace = currNamespaces.find (prefix);
+    if (!existing_namespace || !(*existing_namespace == uri))
+        currNamespaces.appendConstruct(prefix, uri);
     return OK;
 }
 
@@ -1133,7 +1139,7 @@
         return OK;
     if (physical)
         E( physical -> outputElementStart(currElement.getname(), 
-        currNamespaces, currAtts, isEmpty) );
+        currNamespaces, getFirstOwnNS(), currAtts, isEmpty) );
     if (mySAXHandler)
     {
         const char**
diff -ur Sablot-0.41/Sablot/engine/output.h Sablot-0.41-patched/Sablot/engine/output.h
--- Sablot-0.41/Sablot/engine/output.h  Tue Jul 11 15:23:28 2000
+++ Sablot-0.41-patched/Sablot/engine/output.h  Tue Jul 11 16:56:55 2000
@@ -111,7 +111,8 @@
     ~PhysicalOutputLayerObj();
     eFlag setOptions(DataLine *targetDataLine_, OutputDefinition *outDef_);
     eFlag outputElementStart(const Str& name, 
-        const StrStrList& namespaces, const QNameStrList& atts, Bool isEmpty);
+        const StrStrList& namespaces, const int namespace_index,
+        const QNameStrList& atts, Bool isEmpty);
     eFlag outputElementEnd(const Str& name, Bool isEmpty);
     eFlag outputText(const Str& contents, Bool outputEscaping, Bool inHTMLSpecial);
     eFlag outputComment(const Str& contents);
diff -ur Sablot-0.41/Sablot/engine/verts.cpp 
Sablot-0.41-patched/Sablot/engine/verts.cpp
--- Sablot-0.41/Sablot/engine/verts.cpp Tue Jul 11 15:23:28 2000
+++ Sablot-0.41-patched/Sablot/engine/verts.cpp Tue Jul 11 16:56:55 2000
@@ -565,8 +565,8 @@
 eFlag Element::execute(Context *c)
 {
     E( proc -> outputter() -> eventElementStart(name));
-    namespaces.execute(c);
-    atts.execute(c);
+    E( namespaces.execute(c) );
+    E( atts.execute(c) );
     E( Daddy::execute(c) );
     removeBindings();
     E( proc -> outputter() -> eventElementEnd(name));
@@ -1106,6 +1106,7 @@
     if (c -> isFinished())
         return OK;
 
+    c->setCurrentNode(NULL);
     situation.pushCurrV(this);
     Vertex *v = c -> current();
     assert(v);

Reply via email to