You'll be getting a bit bored of these by now.

2005-12-23  Chris Burdess  <[EMAIL PROTECTED]>

        * gnu/xml/stream/SAXParser.java,
          gnu/xml/stream/XMLParser.java: Interim commit during W3C XML
          conformance testing.

The SAX-over-StAX parser is currently scoring 90.33% against the W3C
conformance suite.
-- 
Chris Burdess
  "They that can give up essential liberty to obtain a little safety
  deserve neither liberty nor safety." - Benjamin Franklin
Index: gnu/xml/stream/SAXParser.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/xml/stream/SAXParser.java,v
retrieving revision 1.4
diff -u -r1.4 SAXParser.java
--- gnu/xml/stream/SAXParser.java       18 Dec 2005 12:28:21 -0000      1.4
+++ gnu/xml/stream/SAXParser.java       23 Dec 2005 12:38:52 -0000
@@ -76,7 +76,8 @@
  */
 public class SAXParser
   extends javax.xml.parsers.SAXParser
-  implements XMLReader, Attributes2, Locator2, XMLResolver, XMLReporter
+  implements XMLReader, Attributes2, Locator2, XMLReporter,
+             XMLParser.XMLResolver2
 {
 
   ContentHandler contentHandler;
@@ -377,6 +378,16 @@
                         uri = "";
                         localName = "";
                       }
+                    else
+                      {
+                        int nc = reader.getNamespaceCount();
+                        for (int i = 0; i < nc; i++)
+                          {
+                            String nsuri = reader.getNamespaceURI(i);
+                            String nsprefix = reader.getNamespacePrefix(i);
+                            contentHandler.startPrefixMapping(nsprefix, nsuri);
+                          }
+                      }
                     contentHandler.startElement(uri, localName, qName, this);
                   }
                 break;
@@ -396,6 +407,15 @@
                         localName = "";
                       }
                     contentHandler.endElement(uri, localName, qName);
+                    if (namespaceAware)
+                      {
+                        int nc = reader.getNamespaceCount();
+                        for (int i = 0; i < nc; i++)
+                          {
+                            String nsprefix = reader.getNamespacePrefix(i);
+                            contentHandler.endPrefixMapping(nsprefix);
+                          }
+                      }
                   }
                 break;
               case XMLStreamConstants.COMMENT:
@@ -499,17 +519,26 @@
                             if (ids.notationName != null)
                               {
                                 if (dtdHandler != null)
-                                  dtdHandler.unparsedEntityDecl(name,
-                                                                ids.publicId,
-                                                                ids.systemId,
-                                                                
ids.notationName);
+                                  {
+                                    String pub = ids.publicId;
+                                    String url = ids.systemId;
+                                    String not = ids.notationName;
+                                    dtdHandler.unparsedEntityDecl(name,
+                                                                  pub,
+                                                                  url,
+                                                                  not);
+                                  }
                               }
                             else
                               {
                                 if (declHandler != null)
-                                  declHandler.externalEntityDecl(name,
-                                                                 ids.publicId,
-                                                                 ids.systemId);
+                                  {
+                                    String pub = ids.publicId;
+                                    String url = ids.systemId;
+                                    declHandler.externalEntityDecl(name,
+                                                                   pub,
+                                                                   url);
+                                  }
                               }
                           }
                       }
@@ -520,8 +549,9 @@
                           {
                             XMLParser.ExternalIds ids =
                               doctype.getNotation(name);
-                            dtdHandler.notationDecl(name, ids.publicId,
-                                                    ids.systemId);
+                            String pub = ids.publicId;
+                            String url = ids.systemId;
+                            dtdHandler.notationDecl(name, pub, url);
                           }
                       }
                   }
@@ -536,6 +566,10 @@
           contentHandler.startDocument();
         SAXParseException e2 = new SAXParseException(e.getMessage(), this);
         e2.initCause(e);
+        if (errorHandler != null)
+          errorHandler.fatalError(e2);
+        if (contentHandler != null)
+          contentHandler.endDocument();
         throw e2;
       }
     finally
@@ -607,7 +641,9 @@
 
   public String getType(int index)
   {
-    return reader.getAttributeType(index);
+    String ret = reader.getAttributeType(index);
+    // SAX doesn't permit ENUMERATION?
+    return ("ENUMERATION".equals(ret)) ? "NMTOKEN" : ret;
   }
 
   public String getType(String qName)
@@ -715,15 +751,22 @@
   }
 
   // -- XMLResolver --
-
+  
   public InputStream resolve(String uri)
     throws XMLStreamException
   {
+    return resolve(null, uri);
+  }
+
+  public InputStream resolve(String publicId, String systemId)
+    throws XMLStreamException
+  {
     if (entityResolver != null)
       {
         try
           {
-            InputSource input = entityResolver.resolveEntity(null, uri);
+            InputSource input =
+              entityResolver.resolveEntity(publicId, systemId);
             if (input != null)
               return input.getByteStream();
           }
@@ -777,5 +820,14 @@
           }
       }
   }
+
+  public static void main(String[] args)
+    throws Exception
+  {
+    SAXParser parser = new SAXParser();
+    InputSource input = new InputSource(args[0]);
+    parser.parse(input, new org.xml.sax.helpers.DefaultHandler());
+    
+  }
   
 }
Index: gnu/xml/stream/XMLParser.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/xml/stream/XMLParser.java,v
retrieving revision 1.8
diff -u -r1.8 XMLParser.java
--- gnu/xml/stream/XMLParser.java       18 Dec 2005 12:28:21 -0000      1.8
+++ gnu/xml/stream/XMLParser.java       23 Dec 2005 12:38:52 -0000
@@ -66,8 +66,9 @@
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.LinkedHashMap;
+import java.util.HashSet;
 import java.util.Iterator;
+import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.Map;
 import java.util.NoSuchElementException;
@@ -91,7 +92,7 @@
  * @author <a href='mailto:[EMAIL PROTECTED]'>Chris Burdess</a>
  */
 public class XMLParser
-  implements XMLStreamReader, NamespaceContext, Location
+  implements XMLStreamReader, NamespaceContext
 {
 
   private static final int INIT = 0;
@@ -128,6 +129,7 @@
   private ArrayList attrs = new ArrayList();
   private StringBuffer buf = new StringBuffer();
   private StringBuffer nmtokenBuf = new StringBuffer();
+  private StringBuffer literalBuf = new StringBuffer();
   private char[] tmpBuf = new char[1024];
 
   private String piTarget, piData;
@@ -148,15 +150,15 @@
   private final boolean namespaceAware;
   private final boolean baseAware;
 
-  private final XMLReporter reporter;
-  private final XMLResolver resolver;
+  final XMLReporter reporter;
+  final XMLResolver resolver;
 
   private static final String TEST_START_ELEMENT = "<";
   private static final String TEST_END_ELEMENT = "</";
   private static final String TEST_COMMENT = "<!--";
   private static final String TEST_PI = "<?";
   private static final String TEST_CDATA = "<![CDATA[";
-  private static final String TEST_XML_DECL = "<?xml ";
+  private static final String TEST_XML_DECL = "<?xml";
   private static final String TEST_DOCTYPE_DECL = "<!DOCTYPE";
   private static final String TEST_ELEMENT_DECL = "<!ELEMENT";
   private static final String TEST_ATTLIST_DECL = "<!ATTLIST";
@@ -286,28 +288,6 @@
     return acc.iterator();
   }
 
-  // -- Location --
-
-  public int getCharacterOffset()
-  {
-    return input.offset;
-  }
-
-  public int getColumnNumber()
-  {
-    return input.column;
-  }
-
-  public int getLineNumber()
-  {
-    return input.line;
-  }
-
-  public String getLocationURI()
-  {
-    return input.systemId;
-  }
-
   // -- XMLStreamReader --
 
   public void close()
@@ -370,7 +350,7 @@
         if (att != null)
           return att.type;
       }
-    return null;
+    return "CDATA";
   }
 
   public String getAttributeValue(int index)
@@ -458,7 +438,7 @@
 
   public Location getLocation()
   {
-    return this;
+    return input;
   }
 
   public QName getName()
@@ -782,6 +762,8 @@
       }
     try
       {
+        if (!input.initialized)
+          input.init();
         //System.out.println("input="+input.name+" "+input.inputEncoding);
         switch (state)
           {
@@ -840,7 +822,7 @@
                           }
                         else if (replaceERefs)
                           {
-                            expandEntity(ref); //report start-entity
+                            expandEntity(ref, false); //report start-entity
                             event = next();
                           }
                         else
@@ -857,6 +839,9 @@
               }
             break;
           case EMPTY_ELEMENT:
+            String elementName = (String) stack.removeLast();
+            buf.setLength(0);
+            buf.append(elementName);
             state = stack.isEmpty() ? MISC : CONTENT;
             event = XMLStreamConstants.END_ELEMENT;
             break;
@@ -1072,7 +1057,7 @@
             if (c == '\uffff')
               throw new EOFException();
             else if (c < 32 && c != 10 && c != 9 && c != 13)
-              error("Illegal XML character:", Character.toString(c));
+              error("illegal XML character", Character.toString(c));
             buf.append(c);
           }
       }
@@ -1096,7 +1081,12 @@
         if (white)
           ret = true;
         else if (c == '\uffff')
-          throw new EOFException();
+          {
+            if (inputStack.size() > 1)
+              popInput();
+            else
+              throw new EOFException();
+          }
       }
     while (white);
     reset();
@@ -1114,6 +1104,11 @@
       {
         mark(1);
         char c = readCh();
+        while (c == '\uffff' && inputStack.size() > 1)
+          {
+            popInput();
+            c = readCh();
+          }
         white = (c == ' ' || c == '\t' || c == '\n' || c == '\r');
       }
     while (white);
@@ -1150,6 +1145,13 @@
   private void pushInput(String name, String text)
     throws IOException, XMLStreamException
   {
+    // Check for recursion
+    for (Iterator i = inputStack.iterator(); i.hasNext(); )
+      {
+        Input ctx = (Input) i.next();
+        if (name.equals(ctx.name))
+          error("entities may not be self-recursive", name);
+      }
     pushInput(new Input(null, new StringReader(text), input.publicId,
                         input.systemId, name, input.inputEncoding));
     //System.out.println("pushInput "+name+" "+text);
@@ -1166,18 +1168,47 @@
     InputStream in = null;
     String base = getXMLBase();
     String url = absolutize(base, ids.systemId);
-    // TODO try to resolve via public ID
+    // Unparsed entity?
+    boolean unparsedEntity = false;
+    if (ids.notationName != null)
+      {
+        ExternalIds notation = doctype.getNotation(ids.notationName);
+        if (notation == null)
+          error("reference to undeclared notation", ids.notationName);
+        unparsedEntity = true;
+      }
+    // Check for recursion
+    for (Iterator i = inputStack.iterator(); i.hasNext(); )
+      {
+        Input ctx = (Input) i.next();
+        if (url.equals(ctx.systemId))
+          error("entities may not be self-recursive", url);
+        if (name.equals(ctx.name))
+          error("entities may not be self-recursive", name);
+      }
     if (in == null && url != null && resolver != null)
-      in = resolver.resolve(url);
+      {
+        if (resolver instanceof XMLResolver2)
+          in = ((XMLResolver2) resolver).resolve(ids.publicId, url);
+        else
+          in = resolver.resolve(url);
+      }
     if (in == null)
       in = resolve(url);
     if (in == null)
       error("unable to resolve external entity",
             (ids.systemId != null) ? ids.systemId : ids.publicId);
-    pushInput(new Input(in, ids.publicId, url, name, input.inputEncoding));
-    input.init();
-    if (tryRead(TEST_XML_DECL))
-      readTextDecl();
+    if (unparsedEntity)
+      {
+        // TODO read unparsed entity into buf
+      }
+    else
+      {
+        pushInput(new Input(in, ids.publicId, url, name, input.inputEncoding));
+        input.init();
+        if (tryRead(TEST_XML_DECL))
+          readTextDecl();
+      }
     //System.out.println("pushInput "+name+" "+url);
   }
 
@@ -1273,7 +1304,7 @@
   private void popInput()
   {
     Input old = (Input) inputStack.removeLast();
-    if (startEntityStack.contains(old.name))
+    if (!"".equals(old.name))
       endEntityStack.addFirst(old.name);
     input = (Input) inputStack.getLast();
     //System.out.print("\n(-input:"+input.systemId+")"); 
@@ -1287,6 +1318,7 @@
     throws IOException, XMLStreamException
   {
     final int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF;
+    requireWhitespace();
     if (tryRead("version"))
       {
         readEq();
@@ -1316,6 +1348,7 @@
   {
     final int flags = LIT_DISABLE_CREF | LIT_DISABLE_PE | LIT_DISABLE_EREF;
     
+    requireWhitespace();
     require("version");
     readEq();
     xmlVersion = readLiteral(flags);
@@ -1386,7 +1419,7 @@
             else
               {
                 peIsError = expandPE = true;
-                readMarkupdecl();
+                readMarkupdecl(false);
                 peIsError = expandPE = false;
               }
           }
@@ -1397,7 +1430,7 @@
     // Parse external subset
     if (ids.systemId != null && externalEntities)
       {
-        pushInput(null, ">");
+        pushInput("", ">");
         pushInput("[dtd]", ids);
         // loop until we get back to ">"
         while (true)
@@ -1414,9 +1447,11 @@
             else
               {
                 reset();
-                peIsError = expandPE = true;
-                readMarkupdecl();
-                peIsError = expandPE = false;
+                //peIsError = expandPE = true;
+                expandPE = true;
+                readMarkupdecl(true);
+                //peIsError = expandPE = false;
+                expandPE = true;
               }
           }
         if (inputStack.size() != 2)
@@ -1429,7 +1464,7 @@
     buf.append(rootName);
   }
 
-  private void readMarkupdecl()
+  private void readMarkupdecl(boolean inExternalSubset)
     throws IOException, XMLStreamException
   {
     boolean saved = expandPE;
@@ -1450,12 +1485,12 @@
     else if (tryRead(TEST_ENTITY_DECL))
       {
         expandPE = saved;
-        readEntityDecl();
+        readEntityDecl(inExternalSubset);
       }
     else if (tryRead(TEST_NOTATION_DECL))
       {
         expandPE = saved;
-        readNotationDecl();
+        readNotationDecl(inExternalSubset);
       }
     else if (tryRead(TEST_PI))
       {
@@ -1481,7 +1516,7 @@
             skipWhitespace();
             while (!tryRead("]]>"))
               {
-                readMarkupdecl();
+                readMarkupdecl(inExternalSubset);
                 skipWhitespace();
               }
           }
@@ -1823,7 +1858,7 @@
     doctype.addAttributeDecl(elementName, name, attribute);
   }
 
-  private void readEntityDecl()
+  private void readEntityDecl(boolean inExternalSubset)
     throws IOException, XMLStreamException
   {
     int flags = 0;
@@ -1840,7 +1875,7 @@
     // Read entity name
     String name = readNmtoken(true);
     if (name.indexOf(':') != -1)
-      error("Illegal character ':' in entity name", name);
+      error("illegal character ':' in entity name", name);
     if (peFlag)
       name = "%" + name;
     requireWhitespace();
@@ -1850,8 +1885,8 @@
     if (c == '"' || c == '\'')
       {
         // Internal entity replacement text
-        String value = readLiteral(flags);
-        doctype.addEntityDecl(name, value);
+        String value = readLiteral(flags | LIT_DISABLE_EREF);
+        doctype.addEntityDecl(name, value, inExternalSubset);
       }
     else
       {
@@ -1865,30 +1900,30 @@
             requireWhitespace();
             ids.notationName = readNmtoken(true);
           }
-        doctype.addEntityDecl(name, ids);
+        doctype.addEntityDecl(name, ids, inExternalSubset);
       }
     // finish
     skipWhitespace();
     require('>');
   }
 
-  private void readNotationDecl()
+  private void readNotationDecl(boolean inExternalSubset)
     throws IOException, XMLStreamException
   {
     requireWhitespace();
     String notationName = readNmtoken(true);
     if (notationName.indexOf(':') != -1)
-      error("Illegal character ':' in notation name", notationName);
+      error("illegal character ':' in notation name", notationName);
     requireWhitespace();
     ExternalIds ids = readExternalIds(true, false);
     ids.notationName = notationName;
-    doctype.addNotationDecl(notationName, ids);
+    doctype.addNotationDecl(notationName, ids, inExternalSubset);
     skipWhitespace();
     require('>');
   }
 
   /**
-   * Returns a tuple {publicId, syatemId}.
+   * Returns a tuple {publicId, systemId}.
    */
   private ExternalIds readExternalIds(boolean inNotation, boolean isSubset)
     throws IOException, XMLStreamException
@@ -1908,12 +1943,12 @@
             c = readCh();
             reset();
             if (c == '"' || c == '\'')
-              ids.systemId = readLiteral(flags);
+              ids.systemId = absolutize(input.systemId, readLiteral(flags));
           }
         else
           {
             requireWhitespace();
-            ids.systemId = readLiteral(flags);
+            ids.systemId = absolutize(input.systemId, readLiteral(flags));
           }
 
         for (int i = 0; i < ids.publicId.length(); i++)
@@ -1932,7 +1967,7 @@
     else if (tryRead("SYSTEM"))
       {
         requireWhitespace();
-        ids.systemId = readLiteral(flags);
+        ids.systemId = absolutize(input.systemId, readLiteral(flags));
       }
     else if (!isSubset)
       {
@@ -2000,15 +2035,8 @@
                 if (ctx.containsKey(attName.substring(6)))
                   continue; // namespace was specified
               }
-            else
-              {
-                for (Iterator j = attrs.iterator(); j.hasNext(); )
-                  {
-                    Attribute a = (Attribute) j.next();
-                    if (attName.equals(a.name))
-                      continue; // attribute was specified
-                  }
-              }
+            else if (attributeSpecified(attName))
+              continue;
             AttributeDecl decl = (AttributeDecl) entry.getValue();
             if (decl.value == null)
               continue;
@@ -2031,11 +2059,11 @@
     // make element name available for read
     buf.setLength(0);
     buf.append(elementName);
+    // push element onto stack
+    stack.addLast(elementName);
     switch (c)
       {
       case '>':
-        // push element onto stack
-        stack.addLast(elementName);
         return CONTENT;
       case '/':
         require('>');
@@ -2044,6 +2072,17 @@
     return -1; // to satisfy compiler
   }
 
+  private boolean attributeSpecified(String attName)
+  {
+    for (Iterator j = attrs.iterator(); j.hasNext(); )
+      {
+        Attribute a = (Attribute) j.next();
+        if (attName.equals(a.name))
+          return true;
+      }
+    return false;
+  }
+
   /**
    * Parse an attribute.
    */
@@ -2155,9 +2194,9 @@
     expandPE = false;
     piTarget = readNmtoken(true);
     if (piTarget.indexOf(':') != -1)
-      error("Illegal character in PI target", new Character(':'));
+      error("illegal character in PI target", new Character(':'));
     if ("xml".equalsIgnoreCase(piTarget))
-      error("Illegal PI target", piTarget);
+      error("illegal PI target", piTarget);
     if (tryRead(TEST_END_PI))
       piData = null;
     else
@@ -2278,10 +2317,11 @@
                       buf.append(text);
                     else
                       {
-                        if (replaceERefs)
-                          expandEntity(entityName); //report start-entity
-                        else
-                          reset(); // report reference
+                        //if (replaceERefs)
+                        //  expandEntity(entityName, false); //report 
start-entity
+                        //else
+                        //  reset(); // report reference
+                        pushInput("", "&" + entityName + ";");
                         done = true;
                         break;
                       }
@@ -2302,6 +2342,14 @@
                   }
                 entities = true;
                 break; // end of text sequence
+              case '>':
+                int l = buf.length();
+                if (l > 1 &&
+                    buf.charAt(l - 1) == ']' &&
+                    buf.charAt(l - 2) == ']')
+                  error("Character data may not contain unescaped ']]>'");
+                buf.append(c);
+                break;
               case '<':
                 reset();
                 read(tmpBuf, 0, i);
@@ -2325,14 +2373,14 @@
           done = true;
       }
     if (entities)
-      normalizeCRLF();
+      normalizeCRLF(buf);
     return white ? XMLStreamConstants.SPACE : XMLStreamConstants.CHARACTERS;
   }
 
   /**
    * Expands the specified entity.
    */
-  private void expandEntity(String name)
+  private void expandEntity(String name, boolean inAttr)
     throws IOException, XMLStreamException
   {
     if (doctype != null)
@@ -2340,8 +2388,28 @@
         Object value = doctype.getEntity(name);
         if (value != null)
           {
+            if (xmlStandalone == Boolean.TRUE)
+              {
+                if (doctype.isEntityExternal(name))
+                  error("reference to external entity in standalone document");
+                else if (value instanceof ExternalIds)
+                  {
+                    ExternalIds ids = (ExternalIds) value;
+                    if (ids.notationName != null &&
+                        doctype.isNotationExternal(ids.notationName))
+                      error("reference to external notation in " +
+                            "standalone document");
+                  }
+              }
             if (value instanceof String)
-              pushInput(name, (String) value);
+              {
+                String text = (String) value;
+                if (inAttr && text.indexOf('<') != -1)
+                  error("< in attribute value");
+                pushInput(name, text);
+              }
+            else if (inAttr)
+              error("reference to external entity in attribute value", name);
             else
               pushInput(name, (ExternalIds) value);
             if (name != null)
@@ -2349,7 +2417,7 @@
             return;
           }
       }
-    error("Reference to undeclared entity", name);
+    error("reference to undeclared entity", name);
   }
 
   /**
@@ -2389,12 +2457,16 @@
     char delim = readCh();
     if (delim != '\'' && delim != '"')
       error("expected '\"' or \"'\"", new Character(delim));
-    buf.setLength(0);
+    literalBuf.setLength(0);
     if ((flags & LIT_DISABLE_PE) != 0)
       expandPE = false;
     boolean entities = false;
-    for (char c = literalReadCh(); c != delim; c = literalReadCh())
+    int inputStackSize = inputStack.size();
+    do
       {
+        char c = literalReadCh();
+        if (c == delim && inputStackSize == inputStack.size())
+          break;
         switch (c)
           {
           case '\n':
@@ -2412,61 +2484,83 @@
             if (c == '#')
               {
                 if ((flags & LIT_DISABLE_CREF) != 0)
-                  error("literal may not contain character reference");
-                mark(1);
-                c = readCh();
-                boolean hex = (c == 'x');
-                if (!hex)
-                  reset();
-                char[] ref = readCharacterRef(hex ? 16 : 10);
-                for (int i = 0; i < ref.length; i++)
                   {
-                    c = ref[i];
-                    if ((flags & (LIT_ATTRIBUTE | LIT_PUBID)) != 0 &&
-                        (c == '\n' || c == '\r'))
-                      c = ' '; // normalize
-                    else if ((flags & LIT_ATTRIBUTE) != 0 && c == '\t')
-                      c = ' '; // normalize
-                    buf.append(c);
+                    reset();
+                    c = '&';
+                  }
+                else
+                  {
+                    mark(1);
+                    c = readCh();
+                    boolean hex = (c == 'x');
+                    if (!hex)
+                      reset();
+                    char[] ref = readCharacterRef(hex ? 16 : 10);
+                    for (int i = 0; i < ref.length; i++)
+                      {
+                        c = ref[i];
+                        if ((flags & (LIT_ATTRIBUTE | LIT_PUBID)) != 0 &&
+                            (c == '\n' || c == '\r'))
+                          c = ' '; // normalize
+                        else if ((flags & LIT_ATTRIBUTE) != 0 && c == '\t')
+                          c = ' '; // normalize
+                        literalBuf.append(c);
+                      }
+                    entities = true;
+                    continue;
                   }
-                entities = true;
-                continue;
               }
             else
               {
                 if ((flags & LIT_DISABLE_EREF) != 0)
-                  error("literal may not contain entity reference");
-                reset();
-                if (replaceERefs || (flags & LIT_NORMALIZE) > 0)
                   {
-                    String entityName = readNmtoken(true);
-                    require(';');
-                    String text = (String) PREDEFINED_ENTITIES.get(entityName);
-                    if (text != null)
-                      buf.append(text);
-                    else
-                      expandEntity(entityName);
-                    entities = true;
-                    continue;
+                    reset();
+                    c = '&';
                   }
                 else
-                  error("parser is configured not to replace entity " +
-                        "references");
+                  {
+                    reset();
+                    if (replaceERefs || (flags & LIT_NORMALIZE) > 0)
+                      {
+                        String entityName = readNmtoken(true);
+                        require(';');
+                        String text =
+                          (String) PREDEFINED_ENTITIES.get(entityName);
+                        if (text != null)
+                          literalBuf.append(text);
+                        else
+                          expandEntity(entityName,
+                                       (flags & LIT_ATTRIBUTE) != 0);
+                        entities = true;
+                        continue;
+                      }
+                    else
+                      error("parser is configured not to replace entity " +
+                            "references");
+                  }
               }
             break;
           case '<':
             if ((flags & LIT_ATTRIBUTE) != 0)
               error("attribute values may not contain '<'");
             break;
+          case '\uffff':
+            if (inputStack.size() > 1)
+              {
+                popInput();
+                continue;
+              }
+            throw new EOFException();
           }
-        buf.append(c);
+        literalBuf.append(c);
       }
+    while (true);
     expandPE = saved;
     if (entities)
-      normalizeCRLF();
+      normalizeCRLF(literalBuf);
     if ((flags & LIT_NORMALIZE) > 0)
-      normalize();
-    return buf.toString();
+      literalBuf = normalize(literalBuf);
+    return literalBuf.toString();
   }
 
   /**
@@ -2474,7 +2568,7 @@
    * This discards leading and trailing whitespace, and replaces sequences
    * of whitespace with a single space.
    */
-  private void normalize()
+  private StringBuffer normalize(StringBuffer buf)
   {
     StringBuffer acc = new StringBuffer();
     int len = buf.length();
@@ -2492,7 +2586,7 @@
             avState = 2;
           }
       }
-    buf = acc;
+    return acc;
   }
 
   /**
@@ -2500,7 +2594,7 @@
    * This may be necessary if combinations of CR or LF were declared as
    * (character) entity references in the input.
    */
-  private void normalizeCRLF()
+  private void normalizeCRLF(StringBuffer buf)
   {
     int len = buf.length() - 1;
     for (int i = 0; i < len; i++)
@@ -2522,18 +2616,29 @@
   {
     String name = readNmtoken(true);
     require(';');
+    mark(1); // ensure we don't reset to before the semicolon
     if (doctype != null)
       {
-        Object entity = doctype.getEntity("%" + name);
+        String entityName = "%" + name;
+        Object entity = doctype.getEntity(entityName);
         if (entity != null)
           {
+            if (xmlStandalone == Boolean.TRUE)
+              {
+                if (doctype.isEntityExternal(entityName))
+                  error("reference to external parameter entity in " +
+                        "standalone document");
+              }
             if (entity instanceof String)
               pushInput(name, (String) entity);
             else
               pushInput(name, (ExternalIds) entity);
           }
+        else
+          error("reference to undeclared parameter entity", name);
       }
-    error("reference to undeclared parameter entity", name);
+    else
+      error("reference to parameter entity without doctype", name);
   }
 
   private char[] readCharacterRef(int base)
@@ -2888,6 +2993,8 @@
     private final LinkedHashMap entities = new LinkedHashMap();
     private final LinkedHashMap notations = new LinkedHashMap();
     private final LinkedList entries = new LinkedList();
+    private final HashSet externalEntities = new HashSet();
+    private final HashSet externalNotations = new HashSet();
 
     Doctype(String rootName, String publicId, String systemId)
     {
@@ -2920,28 +3027,34 @@
         entries.add(key);
     }
 
-    void addEntityDecl(String name, String text)
+    void addEntityDecl(String name, String text, boolean inExternalSubset)
     {
       if (entities.containsKey(name))
         return;
       entities.put(name, text);
       entries.add("e" + name);
+      if (inExternalSubset)
+        externalEntities.add(name);
     }
     
-    void addEntityDecl(String name, ExternalIds ids)
+    void addEntityDecl(String name, ExternalIds ids, boolean inExternalSubset)
     {
       if (entities.containsKey(name))
         return;
       entities.put(name, ids);
       entries.add("e" + name);
+      if (inExternalSubset)
+        externalEntities.add(name);
     }
 
-    void addNotationDecl(String name, ExternalIds ids)
+    void addNotationDecl(String name, ExternalIds ids, boolean 
inExternalSubset)
     {
       if (notations.containsKey(name))
         return;
       notations.put(name, ids);
       entries.add("n" + name);
+      if (inExternalSubset)
+        externalNotations.add(name);
     }
 
     String getElementModel(String name)
@@ -2973,11 +3086,21 @@
       return entities.get(name);
     }
 
+    boolean isEntityExternal(String name)
+    {
+      return externalEntities.contains(name);
+    }
+
     ExternalIds getNotation(String name)
     {
       return (ExternalIds) notations.get(name);
     }
 
+    boolean isNotationExternal(String name)
+    {
+      return externalNotations.contains(name);
+    }
+
     Iterator entryIterator()
     {
       return entries.iterator();
@@ -3011,7 +3134,17 @@
     
   }
 
+  interface XMLResolver2
+    extends XMLResolver
+  {
+
+    InputStream resolve(String publicId, String systemId)
+      throws XMLStreamException;
+
+  }
+
   static class Input
+    implements Location
   {
     
     int line = 1, markLine;
@@ -3075,6 +3208,29 @@
           reader = new CRLFReader(reader);
         }
       this.reader = reader;
+      initialized = false;
+    }
+
+    // -- Location --
+    
+    public int getCharacterOffset()
+    {
+      return offset;
+    }
+    
+    public int getColumnNumber()
+    {
+      return column;
+    }
+
+    public int getLineNumber()
+    {
+      return line;
+    }
+
+    public String getLocationURI()
+    {
+      return systemId;
     }
 
     void init()
@@ -3106,6 +3262,8 @@
       offset++;
       int ret = reader.read();
       //System.out.println("read1:"+((char) ret));
+      if (ret == 0x0d)
+        ret = 0x0a;
       if (ret == 0x0a)
         {
           line++;
@@ -3129,6 +3287,11 @@
           for (int i = 0; i < ret; i++)
             {
               char c = b[off + i];
+              if (c == 0x0d)
+                {
+                  c = 0x0a;
+                  b[off + i] = c;
+                }
               if (c == 0x0a)
                 {
                   line++;
@@ -3251,6 +3414,22 @@
           reader = new XMLInputStreamReader((XMLInputStreamReader) reader,
                                             encoding);
         }
+      else
+        {
+          /*if (reporter != null)
+            {
+            try
+            {
+            reporter.report("unable to set input encoding '" + encoding +
+            "': input is specified as reader", "WARNING",
+            encoding, this);
+            }
+            catch (XMLStreamException e)
+            {
+          // Am I bothered?
+          }}*/
+          System.err.println("Can't set input encoding "+encoding);
+        }
     }
 
   }

Attachment: pgp5V931dXBYK.pgp
Description: PGP signature

_______________________________________________
Classpath-patches mailing list
Classpath-patches@gnu.org
http://lists.gnu.org/mailman/listinfo/classpath-patches

Reply via email to