You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by de...@apache.org on 2006/03/13 17:32:38 UTC

svn commit: r385589 - in /xmlgraphics/batik/trunk: sources/org/apache/batik/parser/PathParser.java test-resources/org/apache/batik/parser/unitTesting.xml

Author: deweese
Date: Mon Mar 13 08:32:34 2006
New Revision: 385589

URL: http://svn.apache.org/viewcvs?rev=385589&view=rev
Log:
1) Improved Path parser so it is more conformant.
   a) Doesn't allow comma before 'path' commands. (i.e. h 3, h)
   b) Doesn't allow 'empty' path commands (i.e. "l l 1,2")

Modified:
    xmlgraphics/batik/trunk/sources/org/apache/batik/parser/PathParser.java
    xmlgraphics/batik/trunk/test-resources/org/apache/batik/parser/unitTesting.xml

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/parser/PathParser.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/parser/PathParser.java?rev=385589&r1=385588&r2=385589&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/parser/PathParser.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/parser/PathParser.java Mon Mar 13 08:32:34 2006
@@ -1,6 +1,6 @@
 /*
 
-   Copyright 2000-2003  The Apache Software Foundation 
+   Copyright 2000-2003  The Apache Software Foundation
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@
      * Creates a new PathParser.
      */
     public PathParser() {
-	pathHandler = DefaultPathHandler.INSTANCE;
+        pathHandler = DefaultPathHandler.INSTANCE;
     }
 
     /**
@@ -52,21 +52,21 @@
      * @param handler The transform list handler.
      */
     public void setPathHandler(PathHandler handler) {
-	pathHandler = handler;
+        pathHandler = handler;
     }
 
     /**
      * Returns the path handler in use.
      */
     public PathHandler getPathHandler() {
-	return pathHandler;
+        return pathHandler;
     }
 
     protected void doParse() throws ParseException, IOException {
-	pathHandler.startPath();
+        pathHandler.startPath();
 
-	current = reader.read();
-	loop: for (;;) {
+        current = reader.read();
+        loop: for (;;) {
             try {
                 switch (current) {
                 case 0xD:
@@ -80,265 +80,256 @@
                     current = reader.read();
                     pathHandler.closePath();
                     break;
-                case 'm':
-                    parsem();
-                case 'l':
-                    parsel();
-                    break;
-                case 'M':
-                    parseM();
-                case 'L':
-                    parseL();
-                    break;
-                case 'h':
-                    parseh();
-                    break;
-                case 'H':
-                    parseH();
-                    break;
-                case 'v':
-                    parsev();
-                    break;
-                case 'V':
-                    parseV();
-                    break;
-                case 'c':
-                    parsec();
-                    break;
-                case 'C':
-                    parseC();
-                    break;
-                case 'q':
-                    parseq();
-                    break;
-                case 'Q':
-                    parseQ();
-                    break;
-                case 's':
-                    parses();
-                    break;
-                case 'S':
-                    parseS();
-                    break;
-                case 't':
-                    parset();
-                    break;
-                case 'T':
-                    parseT();
-                    break;
-                case 'a':
-                    parsea();
-                    break;
-                case 'A':
-                    parseA();
-                    break;
-                case -1:
-                    break loop;
+                case 'm': parsem(); break;
+                case 'M': parseM(); break;
+                case 'l': parsel(); break;
+                case 'L': parseL(); break;
+                case 'h': parseh(); break;
+                case 'H': parseH(); break;
+                case 'v': parsev(); break;
+                case 'V': parseV(); break;
+                case 'c': parsec(); break;
+                case 'C': parseC(); break;
+                case 'q': parseq(); break;
+                case 'Q': parseQ(); break;
+                case 's': parses(); break;
+                case 'S': parseS(); break;
+                case 't': parset(); break;
+                case 'T': parseT(); break;
+                case 'a': parsea(); break;
+                case 'A': parseA(); break;
+                case -1:  break loop;
                 default:
-                    reportError("character.unexpected",
-                                new Object[] { new Integer(current) });
-                    skipSubPath();
+                    reportUnexpected(current);
+                    break;
                 }
-	    } catch (ParseException e) {
+            } catch (ParseException e) {
                 errorHandler.error(e);
                 skipSubPath();
             }
-	}
+        }
 
-	skipSpaces();
-	if (current != -1) {
-	    reportError("end.of.stream.expected",
-			new Object[] { new Integer(current) });
-	}
+        skipSpaces();
+        if (current != -1) {
+            reportError("end.of.stream.expected",
+                        new Object[] { new Integer(current) });
+        }
 
-	pathHandler.endPath();
+        pathHandler.endPath();
     }
 
     /**
      * Parses a 'm' command.
      */
     protected void parsem() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
 
         float x = parseFloat();
         skipCommaSpaces();
         float y = parseFloat();
-
         pathHandler.movetoRel(x, y);
-        skipCommaSpaces();
-    }
 
-    /**
-     * Parses a 'l' command.
-     */
-    protected void parsel() throws ParseException, IOException {
-	if (current == 'l') {
-	    current = reader.read();
-	}
-	skipSpaces();
-        for (;;) {
-	    switch (current) {
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-                float x = parseFloat();
-                skipCommaSpaces();
-                float y = parseFloat();
-
-                pathHandler.linetoRel(x, y);
-		break;
-	    default:
-		return;
-	    }
-	    skipCommaSpaces();
-	}
+        boolean expectNumber = skipCommaSpaces2();
+        _parsel(expectNumber);
     }
 
     /**
      * Parses a 'M' command.
      */
     protected void parseM() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
 
         float x = parseFloat();
         skipCommaSpaces();
         float y = parseFloat();
-	    
         pathHandler.movetoAbs(x, y);
-        skipCommaSpaces();
+
+        boolean expectNumber = skipCommaSpaces2();
+        _parseL(expectNumber);
+    }
+
+    /**
+     * Parses a 'l' command.
+     */
+    protected void parsel() throws ParseException, IOException {
+	    current = reader.read();
+        skipSpaces();
+        _parsel(true);
+    }
+
+    protected void _parsel(boolean expectNumber)
+        throws ParseException, IOException {
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
+            float x = parseFloat();
+            skipCommaSpaces();
+            float y = parseFloat();
+
+            pathHandler.linetoRel(x, y);
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'L' command.
      */
     protected void parseL() throws ParseException, IOException {
-	if (current == 'L') {
 	    current = reader.read();
-	}
-	skipSpaces();
+        skipSpaces();
+        _parseL(true);
+    }
+
+    protected void _parseL(boolean expectNumber)
+        throws ParseException, IOException {
         for (;;) {
-	    switch (current) {
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-                float x = parseFloat();
-                skipCommaSpaces();
-                float y = parseFloat();
-
-                pathHandler.linetoAbs(x, y);
-                break;
-	    default:
-                return;
-	    }
-	    skipCommaSpaces();
-	}
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
+            float x = parseFloat();
+            skipCommaSpaces();
+            float y = parseFloat();
+            
+            pathHandler.linetoAbs(x, y);
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'h' command.
      */
     protected void parseh() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
 
-	for (;;) {
-	    switch (current) {
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-                float x = parseFloat();
-                pathHandler.linetoHorizontalRel(x);
-		break;
-	    default:
-		return;
-	    }
-	    skipCommaSpaces();
-	}
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
+            float x = parseFloat();
+            pathHandler.linetoHorizontalRel(x);
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'H' command.
      */
     protected void parseH() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
 
-	for (;;) {
-	    switch (current) {
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-                float x = parseFloat();
-                pathHandler.linetoHorizontalAbs(x);
-		break;
-	    default:
-		return;
-	    }
-	    skipCommaSpaces();
-	}
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
+            float x = parseFloat();
+            pathHandler.linetoHorizontalAbs(x);
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'v' command.
      */
     protected void parsev() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
 
-	for (;;) {
-	    switch (current) {
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-                float x = parseFloat();
-                pathHandler.linetoVerticalRel(x);
-		break;
-	    default:
-		return;
-	    }
-	    skipCommaSpaces();
-	}
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
+            float x = parseFloat();
+
+            pathHandler.linetoVerticalRel(x);
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'V' command.
      */
     protected void parseV() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
+
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
 
-	for (;;) {
-	    switch (current) {
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-                float x = parseFloat();
-                pathHandler.linetoVerticalAbs(x);
-		break;
-	    default:
-		return;
-	    }
-	    skipCommaSpaces();
-	}
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
+            float x = parseFloat();
+
+            pathHandler.linetoVerticalAbs(x);
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'c' command.
      */
     protected void parsec() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
-	
-	for (;;) {
-	    switch (current) {
-	    default:
-		return;
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-	    }
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
+
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
 
             float x1 = parseFloat();
             skipCommaSpaces();
@@ -353,25 +344,29 @@
             float y = parseFloat();
 
             pathHandler.curvetoCubicRel(x1, y1, x2, y2, x, y);
-	    skipCommaSpaces();
-	}
-    }		
+            expectNumber = skipCommaSpaces2();
+        }
+    }
 
     /**
      * Parses a 'C' command.
      */
     protected void parseC() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
-	
-	for (;;) {
-	    switch (current) {
-	    default:
-		return;
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-	    }
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
+
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
 
             float x1 = parseFloat();
             skipCommaSpaces();
@@ -386,25 +381,29 @@
             float y = parseFloat();
 
             pathHandler.curvetoCubicAbs(x1, y1, x2, y2, x, y);
-	    skipCommaSpaces();
-	}
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'q' command.
      */
     protected void parseq() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
+
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
 
-	for (;;) {
-	    switch (current) {
-	    default:
-		return;
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-	    }
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
 
             float x1 = parseFloat();
             skipCommaSpaces();
@@ -415,25 +414,29 @@
             float y = parseFloat();
 
             pathHandler.curvetoQuadraticRel(x1, y1, x, y);
-	    skipCommaSpaces();
-	}
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'Q' command.
      */
     protected void parseQ() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
 
-	for (;;) {
-	    switch (current) {
-	    default:
-		return;
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-	    }
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
 
             float x1 = parseFloat();
             skipCommaSpaces();
@@ -444,26 +447,30 @@
             float y = parseFloat();
 
             pathHandler.curvetoQuadraticAbs(x1, y1, x, y);
-	    skipCommaSpaces();
-	}
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 's' command.
      */
     protected void parses() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
+
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
 
-	for (;;) {
-	    switch (current) {
-	    default:
-		return;
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-	    }
-	    
             float x2 = parseFloat();
             skipCommaSpaces();
             float y2 = parseFloat();
@@ -473,26 +480,30 @@
             float y = parseFloat();
 
             pathHandler.curvetoCubicSmoothRel(x2, y2, x, y);
-	    skipCommaSpaces();
-	}
-    }		
+            expectNumber = skipCommaSpaces2();
+        }
+    }
 
     /**
      * Parses a 'S' command.
      */
     protected void parseS() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
+
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
 
-	for (;;) {
-	    switch (current) {
-	    default:
-		return;
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-	    }
-	    
             float x2 = parseFloat();
             skipCommaSpaces();
             float y2 = parseFloat();
@@ -502,75 +513,87 @@
             float y = parseFloat();
 
             pathHandler.curvetoCubicSmoothAbs(x2, y2, x, y);
-	    skipCommaSpaces();
-	}
-    }		
+            expectNumber = skipCommaSpaces2();
+        }
+    }
 
     /**
      * Parses a 't' command.
      */
     protected void parset() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
 
-	for (;;) {
-	    switch (current) {
-	    default:
-		return;
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-	    }
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
 
             float x = parseFloat();
             skipCommaSpaces();
             float y = parseFloat();
-            
+
             pathHandler.curvetoQuadraticSmoothRel(x, y);
-	    skipCommaSpaces();
-	}		
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'T' command.
      */
     protected void parseT() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
 
-	for (;;) {
-	    switch (current) {
-	    default:
-		return;
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-	    }
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
 
             float x = parseFloat();
             skipCommaSpaces();
             float y = parseFloat();
 
             pathHandler.curvetoQuadraticSmoothAbs(x, y);
-	    skipCommaSpaces();
-	}		
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'a' command.
      */
     protected void parsea() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
 
-	for (;;) {
-	    switch (current) {
-	    default:
-		return;
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-	    }
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
 
             float rx = parseFloat();
             skipCommaSpaces();
@@ -578,20 +601,12 @@
             skipCommaSpaces();
             float ax = parseFloat();
             skipCommaSpaces();
-		
+
             boolean laf;
             switch (current) {
-            case '0':
-                laf = false;
-                break;
-            case '1':
-                laf = true;
-                break;
-            default:
-                reportError("character.unexpected",
-                            new Object[] { new Integer(current) });
-                skipSubPath();
-                return;
+            default:  reportUnexpected(current); return;
+            case '0': laf = false; break;
+            case '1': laf = true;  break;
             }
 
             current = reader.read();
@@ -599,17 +614,9 @@
 
             boolean sf;
             switch (current) {
-            case '0':
-                sf = false;
-                break;
-            case '1':
-                sf = true;
-                break;
-            default:
-                reportError("character.unexpected",
-                            new Object[] { new Integer(current) });
-                skipSubPath();
-                return;
+            default: reportUnexpected(current); return;
+            case '0': sf = false; break;
+            case '1': sf = true;  break;
             }
 
             current = reader.read();
@@ -620,25 +627,29 @@
             float y = parseFloat();
 
             pathHandler.arcRel(rx, ry, ax, laf, sf, x, y);
-	    skipCommaSpaces();
-	}
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Parses a 'A' command.
      */
     protected void parseA() throws ParseException, IOException {
-	current = reader.read();
-	skipSpaces();
+        current = reader.read();
+        skipSpaces();
+        boolean expectNumber = true;
 
-	for (;;) {
-	    switch (current) {
-	    default:
-		return;
-	    case '+': case '-': case '.':
-	    case '0': case '1': case '2': case '3': case '4':
-	    case '5': case '6': case '7': case '8': case '9':
-	    }
+        for (;;) {
+            switch (current) {
+            default:
+                if (expectNumber) reportUnexpected(current);
+                return;
+
+            case '+': case '-': case '.':
+            case '0': case '1': case '2': case '3': case '4':
+            case '5': case '6': case '7': case '8': case '9':
+                break;
+            }
 
             float rx = parseFloat();
             skipCommaSpaces();
@@ -646,38 +657,22 @@
             skipCommaSpaces();
             float ax = parseFloat();
             skipCommaSpaces();
-            
+
             boolean laf;
             switch (current) {
-            case '0':
-                laf = false;
-                break;
-            case '1':
-                laf = true;
-                break;
-            default:
-                reportError("character.unexpected",
-                            new Object[] { new Integer(current) });
-                skipSubPath();
-                return;
+            default: reportUnexpected(current); return;
+            case '0': laf = false; break;
+            case '1': laf = true;  break;
             }
-            
+
             current = reader.read();
             skipCommaSpaces();
 
             boolean sf;
             switch (current) {
-            case '0':
-                sf = false;
-                break;
-            case '1':
-                sf = true;
-                break;
-            default:
-                reportError("character.unexpected",
-                            new Object[] { new Integer(current) });
-                skipSubPath();
-                return;
+            default: reportUnexpected(current); return;
+            case '0': sf = false; break;
+            case '1': sf = true; break;
             }
 
             current = reader.read();
@@ -687,25 +682,51 @@
             float y = parseFloat();
 
             pathHandler.arcAbs(rx, ry, ax, laf, sf, x, y);
-	    skipCommaSpaces();
-	}
+            expectNumber = skipCommaSpaces2();
+        }
     }
 
     /**
      * Skips a sub-path.
      */
     protected void skipSubPath() throws ParseException, IOException {
-	for (;;) {
-	    switch (current) {
-	    case 'm':
-	    case 'M':
-		return;
-	    default:
-		if (current == -1) {
-		    return;
-		}
-		current = reader.read();
-	    }
-	}
+        for (;;) {
+            switch (current) {
+            case -1: case 'm': case 'M': return;
+            default:                     break;
+            }
+            current = reader.read();
+        }
+    }
+
+    protected void reportUnexpected(int ch) 
+        throws ParseException, IOException {
+        reportError("character.unexpected", new Object[] { new Integer(ch) });
+        skipSubPath();
+    }
+
+    /**
+     * Skips the whitespaces and an optional comma.
+     * @returns true if comma was skipped.
+     */
+    protected boolean skipCommaSpaces2() throws IOException {
+        wsp1: for (;;) {
+            switch (current) {
+            default: break wsp1;
+            case 0x20: case 0x9: case 0xD: case 0xA: break;
+            }
+            current = reader.read();
+        }
+
+        if (current != ',') 
+            return false; // no comma.
+
+        wsp2: for (;;) {
+            switch (current = reader.read()) {
+            default: break wsp2;
+            case 0x20: case 0x9: case 0xD: case 0xA: break;
+            }
+        }
+        return true;  // had comma
     }
 }

Modified: xmlgraphics/batik/trunk/test-resources/org/apache/batik/parser/unitTesting.xml
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/test-resources/org/apache/batik/parser/unitTesting.xml?rev=385589&r1=385588&r2=385589&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/test-resources/org/apache/batik/parser/unitTesting.xml (original)
+++ xmlgraphics/batik/trunk/test-resources/org/apache/batik/parser/unitTesting.xml Mon Mar 13 08:32:34 2006
@@ -14,289 +14,443 @@
    limitations under the License.
 -->
 
-<!-- ========================================================================= -->
-<!-- @author stephane@hillion.org                                              -->
+<!-- ================================================================ -->
+<!-- @author stephane@hillion.org                                     -->
 <!-- @version $Id$  -->
-<!-- ========================================================================= -->
-<testSuite id="parser.unitTesting" name="org.apache.batik.parser package - Unit Testing">
-
-    <!-- ========================================================================== -->
-    <!-- LengthParser tests                                                         -->
-    <!-- The first argument is the string to parse                                  -->
-    <!-- The second argument is the expected string                                 -->
-    <!-- ========================================================================== -->
-
-    <test id="lengthParser1" class="org.apache.batik.parser.LengthParserTest" >
-        <arg class="java.lang.String" value="123.456" />
-        <arg class="java.lang.String" value="123.456" />
-    </test>
-
-    <test id="lengthParser2" class="org.apache.batik.parser.LengthParserTest" >
-        <arg class="java.lang.String" value="123em" />
-        <arg class="java.lang.String" value="123.0em" />
-    </test>
-
-    <test id="lengthParser3" class="org.apache.batik.parser.LengthParserTest" >
-        <arg class="java.lang.String" value=".456ex" />
-        <arg class="java.lang.String" value="0.456ex" />
-    </test>
-
-    <test id="lengthParser4" class="org.apache.batik.parser.LengthParserTest" >
-        <arg class="java.lang.String" value="-.456789in" />
-        <arg class="java.lang.String" value="-0.456789in" />
-    </test>
-
-    <test id="lengthParser5" class="org.apache.batik.parser.LengthParserTest" >
-        <arg class="java.lang.String" value="-456789.cm" />
-        <arg class="java.lang.String" value="-456789.0cm" />
-    </test>
-
-    <test id="lengthParser6" class="org.apache.batik.parser.LengthParserTest" >
-        <arg class="java.lang.String" value="-4567890.mm" />
-        <arg class="java.lang.String" value="-4567890.0mm" />
-    </test>
-
-    <test id="lengthParser7" class="org.apache.batik.parser.LengthParserTest" >
-        <arg class="java.lang.String" value="-000456789.pc" />
-        <arg class="java.lang.String" value="-456789.0pc" />
-    </test>
-
-    <test id="lengthParser8" class="org.apache.batik.parser.LengthParserTest" >
-        <arg class="java.lang.String" value="-0.00456789pt" />
-        <arg class="java.lang.String" value="-0.00456789pt" />
-    </test>
-
-    <test id="lengthParser9" class="org.apache.batik.parser.LengthParserTest" >
-        <arg class="java.lang.String" value="-0px" />
-        <arg class="java.lang.String" value="0.0px" />
-    </test>
-
-    <test id="lengthParser10" class="org.apache.batik.parser.LengthParserTest" >
-        <arg class="java.lang.String" value="0000%" />
-        <arg class="java.lang.String" value="0.0%" />
-    </test>
-
-    <!-- ========================================================================== -->
-    <!-- LengthParser failure tests                                                 -->
-    <!-- The argument is the string to parse                                        -->
-    <!-- ========================================================================== -->
-
-    <test id="lengthParserFail1"
-          class="org.apache.batik.parser.LengthParserFailureTest" >
-        <arg class="java.lang.String" value="123.456.7" />
-    </test>
-
-    <test id="lengthParserFail2"
-          class="org.apache.batik.parser.LengthParserFailureTest" >
-        <arg class="java.lang.String" value="1e+" />
-    </test>
-
-    <test id="lengthParserFail3"
-          class="org.apache.batik.parser.LengthParserFailureTest" >
-        <arg class="java.lang.String" value="+e3" />
-    </test>
-
-    <test id="lengthParserFail4"
-          class="org.apache.batik.parser.LengthParserFailureTest" >
-        <arg class="java.lang.String" value="1Em" />
-    </test>
-
-    <test id="lengthParserFail5"
-          class="org.apache.batik.parser.LengthParserFailureTest" >
-        <arg class="java.lang.String" value="--1" />
-    </test>
-
-    <test id="lengthParserFail6"
-          class="org.apache.batik.parser.LengthParserFailureTest" >
-        <arg class="java.lang.String" value="-1E--2" />
-    </test>
-
-    <test id="lengthParserFail7"
-          class="org.apache.batik.parser.LengthParserFailureTest" >
-        <arg class="java.lang.String" value="-.E+1" />
-    </test>
-
-    <test id="lengthParserFail8"
-          class="org.apache.batik.parser.LengthParserFailureTest" >
-        <arg class="java.lang.String" value="-.0EE+1" />
-    </test>
-
-    <test id="lengthParserFail9"
-          class="org.apache.batik.parser.LengthParserFailureTest" >
-        <arg class="java.lang.String" value="1Eem" />
-    </test>
-
-    <test id="lengthParserFail10"
-          class="org.apache.batik.parser.LengthParserFailureTest" >
-        <arg class="java.lang.String" value="1em%" />
-    </test>
-
-    <!-- ========================================================================== -->
-    <!-- PathParser tests                                                           -->
-    <!-- The first argument is the string to parse                                  -->
-    <!-- The second argument is the expected string                                 -->
-    <!-- ========================================================================== -->
-
-    <test id="pathParser1" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2" />
-        <arg class="java.lang.String" value="M1.0 2.0" />
-    </test>
-
-    <test id="pathParser2" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="m1.1 2.0" />
-        <arg class="java.lang.String" value="m1.1 2.0" />
-    </test>
-
-    <test id="pathParser3" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2z" />
-        <arg class="java.lang.String" value="M1.0 2.0Z" />
-    </test>
-
-    <test id="pathParser4" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2e3Z" />
-        <arg class="java.lang.String" value="M1.0 2000.0Z" />
-    </test>
-
-    <test id="pathParser5" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2L 3,4" />
-        <arg class="java.lang.String" value="M1.0 2.0L3.0 4.0" />
-    </test>
-
-    <test id="pathParser6" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2H3.1" />
-        <arg class="java.lang.String" value="M1.0 2.0H3.1" />
-    </test>
-
-    <test id="pathParser7" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2h 3.1" />
-        <arg class="java.lang.String" value="M1.0 2.0h3.1" />
-    </test>
-
-    <test id="pathParser8" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2H 3.1,4" />
-        <arg class="java.lang.String" value="M1.0 2.0H3.1H4.0" />
-    </test>
-
-    <test id="pathParser9" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2h 3.1-4" />
-        <arg class="java.lang.String" value="M1.0 2.0h3.1h-4.0" />
-    </test>
-
-    <test id="pathParser10" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2V3.1e-3" />
-        <arg class="java.lang.String" value="M1.0 2.0V0.0031" />
-    </test>
-
-    <test id="pathParser11" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2V3.1" />
-        <arg class="java.lang.String" value="M1.0 2.0V3.1" />
-    </test>
-
-    <test id="pathParser12" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2v3.1,.4" />
-        <arg class="java.lang.String" value="M1.0 2.0v3.1v0.4" />
-    </test>
-
-    <test id="pathParser13" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2v3.1-.4" />
-        <arg class="java.lang.String" value="M1.0 2.0v3.1v-0.4" />
-    </test>
-
-    <test id="pathParser14" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2C3 4 5 6 7 8" />
-        <arg class="java.lang.String" value="M1.0 2.0C3.0 4.0 5.0 6.0 7.0 8.0" />
-    </test>
-
-    <test id="pathParser15" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2c.3.4.5.6.7.8" />
-        <arg class="java.lang.String" value="M1.0 2.0c0.3 0.4 0.5 0.6 0.7 0.8" />
-    </test>
-
-    <test id="pathParser16" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2S3+4+5+6" />
-        <arg class="java.lang.String" value="M1.0 2.0S3.0 4.0 5.0 6.0" />
-    </test>
-
-    <test id="pathParser17" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2s.3+.4+.5-.6" />
-        <arg class="java.lang.String" value="M1.0 2.0s0.3 0.4 0.5 -0.6" />
-    </test>
-
-    <test id="pathParser18" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2q3. 4.+5 6" />
-        <arg class="java.lang.String" value="M1.0 2.0q3.0 4.0 5.0 6.0" />
-    </test>
-
-    <test id="pathParser19" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2Q.3e0.4.5.6" />
-        <arg class="java.lang.String" value="M1.0 2.0Q0.3 0.4 0.5 0.6" />
-    </test>
-
-    <test id="pathParser20" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2t+.3-.4" />
-        <arg class="java.lang.String" value="M1.0 2.0t0.3 -0.4" />
-    </test>
-
-    <test id="pathParser21" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2T -.3+4" />
-        <arg class="java.lang.String" value="M1.0 2.0T-0.3 4.0" />
-    </test>
-
-    <test id="pathParser22" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2a3 4 5 0,1 6 7" />
-        <arg class="java.lang.String" value="M1.0 2.0a3.0 4.0 5.0 0 1 6.0 7.0" />
-    </test>
-
-    <test id="pathParser23" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2A3 4 5 0,1 6 7" />
-        <arg class="java.lang.String" value="M1.0 2.0A3.0 4.0 5.0 0 1 6.0 7.0" />
-    </test>
-
-    <test id="pathParser24" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2t+.3-.4,5,6" />
-        <arg class="java.lang.String" value="M1.0 2.0t0.3 -0.4t5.0 6.0" />
-    </test>
-
-    <test id="pathParser25" class="org.apache.batik.parser.PathParserTest" >
-        <arg class="java.lang.String" value="M1 2T -.3+4 5-6" />
-        <arg class="java.lang.String" value="M1.0 2.0T-0.3 4.0T5.0 -6.0" />
-    </test>
-
-    <!-- ========================================================================== -->
-    <!-- PathParser failure tests                                                   -->
-    <!-- The argument is the string to parse                                        -->
-    <!-- ========================================================================== -->
-
-    <test id="pathParserFail1"
-          class="org.apache.batik.parser.PathParserFailureTest" >
-        <arg class="java.lang.String" value="m 1ee2 3" />
-    </test>
-
-    <test id="pathParserFail2"
-          class="org.apache.batik.parser.PathParserFailureTest" >
-        <arg class="java.lang.String" value="m 1e4e2 3" />
-    </test>
-
-    <test id="pathParserFail3"
-          class="org.apache.batik.parser.PathParserFailureTest" >
-        <arg class="java.lang.String" value="m 1e+ 2" />
-    </test>
-
-    <test id="pathParserFail4"
-          class="org.apache.batik.parser.PathParserFailureTest" >
-        <arg class="java.lang.String" value="m 1 l 3 4" />
-    </test>
-
-    <test id="pathParserFail5"
-          class="org.apache.batik.parser.PathParserFailureTest" >
-        <arg class="java.lang.String" value="m 1.5.6.7 l 3 4" />
-    </test>
-
-    <!-- ========================================================================== -->
-    <!-- TransformListParser tests                                                  -->
-    <!-- The first argument is the string to parse                                  -->
-    <!-- The second argument is the expected string                                 -->
-    <!-- ========================================================================== -->
+<!-- ================================================================ -->
+<testSuite id="parser.unitTesting" 
+           name="org.apache.batik.parser package - Unit Testing">
+
+    <!-- ================================================================== -->
+    <!-- LengthParser tests                                                 -->
+    <!-- The first argument is the string to parse                          -->
+    <!-- The second argument is the expected string                         -->
+    <!-- ================================================================== -->
+   <testGroup id="lengthParser" 
+              class="org.apache.batik.parser.LengthParserTest">
+      <test id="lengthParser1">
+          <arg class="java.lang.String" value="123.456" />
+          <arg class="java.lang.String" value="123.456" />
+      </test>
+
+      <test id="lengthParser2">
+          <arg class="java.lang.String" value="123em" />
+          <arg class="java.lang.String" value="123.0em" />
+      </test>
+
+      <test id="lengthParser3">
+          <arg class="java.lang.String" value=".456ex" />
+          <arg class="java.lang.String" value="0.456ex" />
+      </test>
+
+      <test id="lengthParser4">
+          <arg class="java.lang.String" value="-.456789in" />
+          <arg class="java.lang.String" value="-0.456789in" />
+      </test>
+
+      <test id="lengthParser5">
+          <arg class="java.lang.String" value="-456789.cm" />
+          <arg class="java.lang.String" value="-456789.0cm" />
+      </test>
+
+      <test id="lengthParser6">
+          <arg class="java.lang.String" value="-4567890.mm" />
+          <arg class="java.lang.String" value="-4567890.0mm" />
+      </test>
+
+      <test id="lengthParser7">
+          <arg class="java.lang.String" value="-000456789.pc" />
+          <arg class="java.lang.String" value="-456789.0pc" />
+      </test>
+
+      <test id="lengthParser8">
+          <arg class="java.lang.String" value="-0.00456789pt" />
+          <arg class="java.lang.String" value="-0.00456789pt" />
+      </test>
+
+      <test id="lengthParser9">
+          <arg class="java.lang.String" value="-0px" />
+          <arg class="java.lang.String" value="0.0px" />
+      </test>
+
+      <test id="lengthParser10">
+          <arg class="java.lang.String" value="0000%" />
+          <arg class="java.lang.String" value="0.0%" />
+      </test>
+   </testGroup>
+
+    <!-- ================================================================== -->
+    <!-- LengthParser failure tests                                         -->
+    <!-- The argument is the string to parse                                -->
+    <!-- ================================================================== -->
+
+   <testGroup id="lengthParserFail"
+              class="org.apache.batik.parser.LengthParserFailureTest">
+
+      <test id="lengthParserFail1">
+          <arg class="java.lang.String" value="123.456.7" />
+      </test>
+
+      <test id="lengthParserFail2">
+          <arg class="java.lang.String" value="1e+" />
+      </test>
+
+      <test id="lengthParserFail3">
+          <arg class="java.lang.String" value="+e3" />
+      </test>
+
+      <test id="lengthParserFail4">
+          <arg class="java.lang.String" value="1Em" />
+      </test>
+
+      <test id="lengthParserFail5">
+          <arg class="java.lang.String" value="--1" />
+      </test>
+
+      <test id="lengthParserFail6">
+          <arg class="java.lang.String" value="-1E--2" />
+      </test>
+
+      <test id="lengthParserFail7">
+          <arg class="java.lang.String" value="-.E+1" />
+      </test>
+
+      <test id="lengthParserFail8">
+          <arg class="java.lang.String" value="-.0EE+1" />
+      </test>
+
+      <test id="lengthParserFail9">
+          <arg class="java.lang.String" value="1Eem" />
+      </test>
+
+      <test id="lengthParserFail10">
+          <arg class="java.lang.String" value="1em%" />
+      </test>
+   </testGroup>
+
+    <!-- ================================================================== -->
+    <!-- PathParser tests                                                   -->
+    <!-- The first argument is the string to parse                          -->
+    <!-- The second argument is the expected string                         -->
+    <!-- ================================================================== -->
+    <testGroup class="org.apache.batik.parser.PathParserTest">
+       <test id="pathParser1" >
+           <arg class="java.lang.String" value="M1 2" />
+           <arg class="java.lang.String" value="M1.0 2.0" />
+       </test>
+
+       <test id="pathParser2" >
+           <arg class="java.lang.String" value="m1.1 2.0" />
+           <arg class="java.lang.String" value="m1.1 2.0" />
+       </test>
+
+       <test id="pathParser3" >
+           <arg class="java.lang.String" value="M1 2z" />
+           <arg class="java.lang.String" value="M1.0 2.0Z" />
+       </test>
+
+       <test id="pathParser4" >
+           <arg class="java.lang.String" value="M1 2e3Z" />
+           <arg class="java.lang.String" value="M1.0 2000.0Z" />
+       </test>
+
+       <test id="pathParser5" >
+           <arg class="java.lang.String" value="M1 2L 3,4" />
+           <arg class="java.lang.String" value="M1.0 2.0L3.0 4.0" />
+       </test>
+
+       <test id="pathParser5.1" >
+           <arg class="java.lang.String" value="M1 2 3,4" />
+           <arg class="java.lang.String" value="M1.0 2.0L3.0 4.0" />
+       </test>
+
+       <test id="pathParser5.2" >
+           <arg class="java.lang.String" value="M1, 2, 3,4" />
+           <arg class="java.lang.String" value="M1.0 2.0L3.0 4.0" />
+       </test>
+
+       <test id="pathParser5.3" >
+           <arg class="java.lang.String" value="m1, 2, 3,4" />
+           <arg class="java.lang.String" value="m1.0 2.0l3.0 4.0" />
+       </test>
+
+       <test id="pathParser6" >
+           <arg class="java.lang.String" value="M1 2H3.1" />
+           <arg class="java.lang.String" value="M1.0 2.0H3.1" />
+       </test>
+
+       <test id="pathParser6.1" >
+           <arg class="java.lang.String" value="M1 2H3.1 4" />
+           <arg class="java.lang.String" value="M1.0 2.0H3.1H4.0" />
+       </test>
+       <test id="pathParser6.2" >
+           <arg class="java.lang.String" value="M1 2H3.1,4" />
+           <arg class="java.lang.String" value="M1.0 2.0H3.1H4.0" />
+       </test>
+
+       <test id="pathParser7" >
+           <arg class="java.lang.String" value="M1 2h 3.1" />
+           <arg class="java.lang.String" value="M1.0 2.0h3.1" />
+       </test>
+       <test id="pathParser7.1" >
+           <arg class="java.lang.String" value="M1 2h 3.1 4" />
+           <arg class="java.lang.String" value="M1.0 2.0h3.1h4.0" />
+       </test>
+       <test id="pathParser7.2" >
+           <arg class="java.lang.String" value="M1 2h 3.1,4" />
+           <arg class="java.lang.String" value="M1.0 2.0h3.1h4.0" />
+       </test>
+
+       <test id="pathParser8" >
+           <arg class="java.lang.String" value="M1 2H 3.1,4" />
+           <arg class="java.lang.String" value="M1.0 2.0H3.1H4.0" />
+       </test>
+
+       <test id="pathParser9" >
+           <arg class="java.lang.String" value="M1 2h 3.1-4" />
+           <arg class="java.lang.String" value="M1.0 2.0h3.1h-4.0" />
+       </test>
+
+       <test id="pathParser10">
+           <arg class="java.lang.String" value="M1 2V3.1e-3" />
+           <arg class="java.lang.String" value="M1.0 2.0V0.0031" />
+       </test>
+
+       <test id="pathParser11">
+           <arg class="java.lang.String" value="M1 2V3.1" />
+           <arg class="java.lang.String" value="M1.0 2.0V3.1" />
+       </test>
+
+       <test id="pathParser12">
+           <arg class="java.lang.String" value="M1 2v3.1,.4" />
+           <arg class="java.lang.String" value="M1.0 2.0v3.1v0.4" />
+       </test>
+
+       <test id="pathParser13">
+           <arg class="java.lang.String" value="M1 2v3.1-.4" />
+           <arg class="java.lang.String" value="M1.0 2.0v3.1v-0.4" />
+       </test>
+
+       <test id="pathParser14">
+           <arg class="java.lang.String" value="M1 2C3 4 5 6 7 8" />
+           <arg class="java.lang.String" 
+                value="M1.0 2.0C3.0 4.0 5.0 6.0 7.0 8.0" />
+       </test>
+
+       <test id="pathParser15">
+           <arg class="java.lang.String" value="M1 2c.3.4.5.6.7.8" />
+           <arg class="java.lang.String" 
+                value="M1.0 2.0c0.3 0.4 0.5 0.6 0.7 0.8" />
+       </test>
+
+       <test id="pathParser16">
+           <arg class="java.lang.String" value="M1 2S3+4+5+6" />
+           <arg class="java.lang.String" value="M1.0 2.0S3.0 4.0 5.0 6.0" />
+       </test>
+
+       <test id="pathParser17">
+           <arg class="java.lang.String" value="M1 2s.3+.4+.5-.6" />
+           <arg class="java.lang.String" value="M1.0 2.0s0.3 0.4 0.5 -0.6" />
+       </test>
+
+       <test id="pathParser18">
+           <arg class="java.lang.String" value="M1 2q3. 4.+5 6" />
+           <arg class="java.lang.String" value="M1.0 2.0q3.0 4.0 5.0 6.0" />
+       </test>
+
+       <test id="pathParser19">
+           <arg class="java.lang.String" value="M1 2Q.3e0.4.5.6" />
+           <arg class="java.lang.String" value="M1.0 2.0Q0.3 0.4 0.5 0.6" />
+       </test>
+
+       <test id="pathParser20">
+           <arg class="java.lang.String" value="M1 2t+.3-.4" />
+           <arg class="java.lang.String" value="M1.0 2.0t0.3 -0.4" />
+       </test>
+
+       <test id="pathParser21">
+           <arg class="java.lang.String" value="M1 2T -.3+4" />
+           <arg class="java.lang.String" value="M1.0 2.0T-0.3 4.0" />
+       </test>
+
+       <test id="pathParser22">
+           <arg class="java.lang.String" value="M1 2a3 4 5 0,1 6 7" />
+           <arg class="java.lang.String" 
+                value="M1.0 2.0a3.0 4.0 5.0 0 1 6.0 7.0" />
+       </test>
+
+       <test id="pathParser23">
+           <arg class="java.lang.String" value="M1 2A3 4 5 0,1 6 7" />
+           <arg class="java.lang.String" 
+                value="M1.0 2.0A3.0 4.0 5.0 0 1 6.0 7.0" />
+       </test>
+
+       <test id="pathParser24">
+           <arg class="java.lang.String" value="M1 2t+.3-.4,5,6" />
+           <arg class="java.lang.String" value="M1.0 2.0t0.3 -0.4t5.0 6.0" />
+       </test>
+
+       <test id="pathParser25">
+           <arg class="java.lang.String" value="M1 2T -.3+4 5-6" />
+           <arg class="java.lang.String" value="M1.0 2.0T-0.3 4.0T5.0 -6.0" />
+       </test>
+    </testGroup>
+
+    <!-- ================================================================== -->
+    <!-- PathParser failure tests                                           -->
+    <!-- The argument is the string to parse                                -->
+    <!-- ================================================================== -->
+
+    <testGroup class="org.apache.batik.parser.PathParserFailureTest">
+       <test id="pathParserFail1">
+           <arg class="java.lang.String" value="m 1ee2 3" />
+       </test>
+
+       <test id="pathParserFail2">
+           <arg class="java.lang.String" value="m 1e4e2 3" />
+       </test>
+
+       <test id="pathParserFail3">
+           <arg class="java.lang.String" value="m 1e+ 2" />
+       </test>
+
+       <test id="pathParserFail4">
+           <arg class="java.lang.String" value="m 1 l 3 4" />
+       </test>
+
+       <test id="pathParserFail5">
+           <arg class="java.lang.String" value="m 1.5.6.7 l 3 4" />
+       </test>
+
+       <test id="pathParserFail6">
+           <arg class="java.lang.String" value="m 1.5,6.7,l 3 4" />
+       </test>
+
+       <test id="pathParserFail7">
+           <arg class="java.lang.String" value="m 1.5,6.7,L 3 4" />
+       </test>
+
+       <test id="pathParserFail8">
+           <arg class="java.lang.String" value="m 1.5,6.7,h 3" />
+       </test>
+
+       <test id="pathParserFail9">
+           <arg class="java.lang.String" value="m 1.5,6.7,H 3" />
+       </test>
+
+       <test id="pathParserFail10">
+           <arg class="java.lang.String" value="m 1.5,6.7,v 3" />
+       </test>
+
+       <test id="pathParserFail11">
+           <arg class="java.lang.String" value="m 1.5,6.7,V 3" />
+       </test>
+
+       <test id="pathParserFail12">
+           <arg class="java.lang.String" value="m 1.5,6.7,c 1,2 3,4 5,6" />
+       </test>
+       <test id="pathParserFail13">
+           <arg class="java.lang.String" value="m 1.5,6.7,C 1,2 3,4 5,6" />
+       </test>
+
+       <test id="pathParserFail14">
+           <arg class="java.lang.String" value="m 1.5,6.7,s 1,2 3,4" />
+       </test>
+       <test id="pathParserFail15">
+           <arg class="java.lang.String" value="m 1.5,6.7,S 1,2 3,4" />
+       </test>
+
+       <test id="pathParserFail16">
+           <arg class="java.lang.String" value="m 1.5,6.7,q 1,2 3,4" />
+       </test>
+       <test id="pathParserFail17">
+           <arg class="java.lang.String" value="m 1.5,6.7,Q 1,2 3,4" />
+       </test>
+
+       <test id="pathParserFail18">
+           <arg class="java.lang.String" value="m 1.5,6.7,t 1,2" />
+       </test>
+       <test id="pathParserFail19">
+           <arg class="java.lang.String" value="m 1.5,6.7,T 1,2" />
+       </test>
+
+       <test id="pathParserFail20">
+           <arg class="java.lang.String" value="m 1.5,6.7,a 2,2 0 1 1 2 2" />
+       </test>
+       <test id="pathParserFail21">
+           <arg class="java.lang.String" value="m 1.5,6.7,A 4,4 0 1 1 2 2" />
+       </test>
+
+       <!-- Check for double path commands -->
+       <test id="pathParserFail22">
+           <arg class="java.lang.String" value="m m 1,2"/>
+       </test>
+       <test id="pathParserFail22.1">
+           <arg class="java.lang.String" value="M M 1,2"/>
+       </test>
+
+       <test id="pathParserFail23">
+           <arg class="java.lang.String" value="m 1,2 l l 3,4 z"/>
+       </test>
+       <test id="pathParserFail24">
+           <arg class="java.lang.String" value="m 1,2 L L 3,4 z"/>
+       </test>
+
+       <test id="pathParserFail25">
+           <arg class="java.lang.String" value="m 1,2 h h 3 z"/>
+       </test>
+       <test id="pathParserFail26">
+           <arg class="java.lang.String" value="m 1,2 H H 3 z"/>
+       </test>
+
+       <test id="pathParserFail27">
+           <arg class="java.lang.String" value="m 1,2 v v 3 z"/>
+       </test>
+       <test id="pathParserFail28">
+           <arg class="java.lang.String" value="m 1,2 V V 3 z"/>
+       </test>
+
+       <test id="pathParserFail29">
+           <arg class="java.lang.String" value="m 1,2 c c 1,2 3,4 5,6z"/>
+       </test>
+       <test id="pathParserFail30">
+           <arg class="java.lang.String" value="m 1,2 C C 1,2 3,4 5,6 z"/>
+       </test>
+
+       <test id="pathParserFail31">
+           <arg class="java.lang.String" value="m 1,2 s s 1,2 3,4 z"/>
+       </test>
+       <test id="pathParserFail32">
+           <arg class="java.lang.String" value="m 1,2 S S 1,2 3,4 z"/>
+       </test>
+
+       <test id="pathParserFail33">
+           <arg class="java.lang.String" value="m 1,2 q q 1,2 3,4 z"/>
+       </test>
+       <test id="pathParserFail34">
+           <arg class="java.lang.String" value="m 1,2 Q Q 1,2 3,4 z"/>
+       </test>
+
+       <test id="pathParserFail35">
+           <arg class="java.lang.String" value="m 1,2 t t 1,2 z"/>
+       </test>
+       <test id="pathParserFail36">
+           <arg class="java.lang.String" value="m 1,2 T T 1,2 z"/>
+       </test>
+
+       <test id="pathParserFail37">
+           <arg class="java.lang.String" value="m 1.5,6.7 a a 2,2 0 1 1 2 2" />
+       </test>
+       <test id="pathParserFail38">
+           <arg class="java.lang.String" value="m 1.5,6.7 A A 4,4 0 1 1 2 2" />
+       </test>
+    </testGroup>
+
+    <!-- ================================================================== -->
+    <!-- TransformListParser tests                                          -->
+    <!-- The first argument is the string to parse                          -->
+    <!-- The second argument is the expected string                         -->
+    <!-- ================================================================== -->
 
     <test id="transformParser1" class="org.apache.batik.parser.TransformListParserTest">
         <arg class="java.lang.String" value="matrix(1 2 3 4 5 6)" />