updating to the latest module.
[mono.git] / mcs / class / Commons.Xml.Relaxng / Commons.Xml.Relaxng.Rnc / RncTokenizer.cs
index a1d2f96aa6c3e71ebcfbf431b3d5ac57277c3e78..747364a5935f424f750ff00e3ec8a68439fe590d 100755 (executable)
@@ -50,8 +50,9 @@ namespace Commons.Xml.Relaxng.Rnc
 \r
                int line = 1;\r
                int column;\r
+               int savedLineNumber = 1;\r
+               int savedLinePosition;\r
                bool nextIncrementLine;\r
-               string prefixName;\r
 \r
                public RncTokenizer (TextReader source)\r
                {\r
@@ -63,11 +64,11 @@ namespace Commons.Xml.Relaxng.Rnc
                }\r
 \r
                public int Line {\r
-                       get { return line; }\r
+                       get { return savedLineNumber; }\r
                }\r
 \r
                public int Column {\r
-                       get { return column; }\r
+                       get { return savedLinePosition; }\r
                }\r
 \r
                // jay interface implementation\r
@@ -79,10 +80,10 @@ namespace Commons.Xml.Relaxng.Rnc
 \r
                public bool advance ()\r
                {\r
-                       if (prefixName != null)\r
-                               throw new RelaxngException ("Invalid prefix was found.");\r
                        tokenValue = null;\r
-                       currentToken = ParseToken ();\r
+                       currentToken = ParseToken (false);\r
+                       savedLineNumber = line;\r
+                       savedLinePosition = column;\r
                        return currentToken != Token.EOF;\r
                }\r
 \r
@@ -137,8 +138,6 @@ namespace Commons.Xml.Relaxng.Rnc
                                return ret;\r
                        ret = source.Read ();\r
                        switch (ret) {\r
-                       case '\\':\r
-                               return ret;\r
                        case 'x':\r
                                int tmp;\r
                                int xcount = 0;\r
@@ -158,7 +157,8 @@ namespace Commons.Xml.Relaxng.Rnc
                                peekChar = 0;\r
                                return ret;\r
                        }\r
-                       throw new RelaxngException ("Invalidly escaped token.");\r
+                       peekString = new string ((char) ret, 1);\r
+                       return '\\';\r
                }\r
 \r
                private int PeekChar ()\r
@@ -245,6 +245,8 @@ namespace Commons.Xml.Relaxng.Rnc
                                default:\r
                                        if (c < 0)\r
                                                throw new RelaxngException ("Unterminated quoted literal.");\r
+                                       if (XmlChar.IsInvalid (c))\r
+                                               throw new RelaxngException ("Invalid character in literal.");\r
                                        AppendNameChar (c, ref index);\r
                                        break;\r
                                }\r
@@ -294,6 +296,8 @@ namespace Commons.Xml.Relaxng.Rnc
                                default:\r
                                        if (c < 0)\r
                                                throw new RelaxngException ("Unterminated triple-quoted literal.");\r
+                                       if (XmlChar.IsInvalid (c))\r
+                                               throw new RelaxngException ("Invalid character in literal.");\r
                                        AppendNameChar (c, ref index);\r
                                        break;\r
                                }\r
@@ -302,12 +306,15 @@ namespace Commons.Xml.Relaxng.Rnc
                        return new string (nameBuffer, 0, index);\r
                }\r
 \r
-               private string ReadOneToken ()\r
+               private string ReadOneName ()\r
                {\r
                        int index = 0;\r
                        bool loop = true;\r
+                       int c = PeekChar ();\r
+                       if (!XmlChar.IsFirstNameChar (c) || !XmlChar.IsNCNameChar (c))\r
+                               throw new RelaxngException (String.Format ("Invalid NCName start character: {0}", c));\r
                        do {\r
-                               int c = PeekChar ();\r
+                               c = PeekChar ();\r
                                switch (c) {\r
                                case -1:\r
                                case ' ':\r
@@ -318,12 +325,7 @@ namespace Commons.Xml.Relaxng.Rnc
                                        loop = false;\r
                                        break;\r
                                default:\r
-                                       if (!IsNCNameChar (c)) {\r
-                                               if (c == ':') {\r
-                                                       if (prefixName != null)\r
-                                                               throw new RelaxngException ("Invalid colon was found.");\r
-                                                       prefixName = new string (nameBuffer, 0, index);\r
-                                               }\r
+                                       if (!XmlChar.IsNCNameChar (c)) {\r
                                                loop = false;\r
                                                break;\r
                                        }\r
@@ -350,35 +352,7 @@ namespace Commons.Xml.Relaxng.Rnc
                        return s;\r
                }\r
 \r
-               private bool IsNCNameChar (int c)\r
-               {\r
-                       switch (c) {\r
-                       case '=':\r
-                       case ':':\r
-                       case ',':\r
-                       case '{':\r
-                       case '}':\r
-                       case '(':\r
-                       case ')':\r
-                       case '[':\r
-                       case ']':\r
-                       case '&':\r
-                       case '|':\r
-                       case '?':\r
-                       case '*':\r
-                       case '\\':\r
-                       case '+':\r
-//                     case '-':\r
-                       case '>':\r
-                       case '#':\r
-                       case '\'':\r
-                       case '\"':\r
-                               return false;\r
-                       }\r
-                       return true;\r
-               }\r
-\r
-               private int ParseToken ()\r
+               private int ParseToken (bool backslashed)\r
                {\r
                        SkipWhitespaces ();\r
                        int c = ReadChar ();\r
@@ -388,19 +362,6 @@ namespace Commons.Xml.Relaxng.Rnc
                                return Token.EOF;\r
                        case '=':\r
                                return Token.Equal;\r
-                       case ':':\r
-                               // return CName\r
-                               if (prefixName == null)\r
-                                       throw new RelaxngException ("Invalid character ':' was found.");\r
-                               if (PeekChar () == '*') {\r
-                                       ReadChar ();\r
-                                       tokenValue = prefixName;\r
-                                       prefixName = null;\r
-                                       return Token.NsName;\r
-                               }\r
-                               tokenValue = prefixName + ":" + ReadOneToken ();\r
-                               prefixName = null;\r
-                               return Token.CName;\r
                        case '~':\r
                                return Token.Tilde;\r
                        case ',':\r
@@ -433,7 +394,9 @@ namespace Commons.Xml.Relaxng.Rnc
                                // See also ':' for NsName\r
                                return Token.Asterisk;\r
                        case '\\':\r
-                               return Token.BackSlash;\r
+                               if (backslashed)\r
+                                       return Token.BackSlash;\r
+                               return ParseToken (true);\r
                        case '+':\r
                                return Token.Plus;\r
                        case '-':\r
@@ -451,7 +414,7 @@ namespace Commons.Xml.Relaxng.Rnc
 //                                     throw new RelaxngException ("Invalid character after '#'.");\r
                                tokenValue = ReadLine ();\r
 //                             return Token.Documentation;\r
-                               return ParseToken ();\r
+                               return ParseToken (false);\r
                        case '\'':\r
                        case '\"':\r
                                if (PeekChar () != c)\r
@@ -467,11 +430,24 @@ namespace Commons.Xml.Relaxng.Rnc
                                tokenValue = name;\r
                                return Token.LiteralSegment;\r
                        default:\r
+                               if (!XmlChar.IsNCNameChar (c))\r
+                                       throw new RelaxngException ("Invalid NCName character.");\r
                                peekChar = c;\r
-                               name = ReadOneToken ();\r
-                               if (prefixName != null)\r
-                                       return ParseToken ();\r
+                               name = ReadOneName ();\r
+                               if (PeekChar () == ':') {\r
+                                       ReadChar ();\r
+                                       if (PeekChar () == '*') {\r
+                                               ReadChar ();\r
+                                               tokenValue = name;\r
+                                               return Token.NsName;\r
+                                       }\r
+                                       tokenValue = name + ":" + ReadOneName ();\r
+                                       return Token.CName;\r
+\r
+                               }\r
                                tokenValue = name;\r
+                               if (backslashed)\r
+                                       return Token.NCName;\r
                                switch (name) {\r
                                case "attribute":\r
                                        isElement = false;\r
@@ -514,7 +490,7 @@ namespace Commons.Xml.Relaxng.Rnc
                                case "token":\r
                                        return Token.KeywordToken;\r
                                default:\r
-                                       return Token.NCNameButKeyword;\r
+                                       return Token.NCName;\r
                                }\r
                        }\r
                }\r