2004-03-17 Francois Beauchemin <beauche@softhome.net>
authorGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Wed, 17 Mar 2004 20:21:43 +0000 (20:21 -0000)
committerGonzalo Paniagua Javier <gonzalo.mono@gmail.com>
Wed, 17 Mar 2004 20:21:43 +0000 (20:21 -0000)
  * syntax.cs, interpreter.cs, quicksearch.cs, regex.cs, compiler.cs :
  Revised support for RigthToLeft.
  quicksearch has now an reverse option.
  This fixes bug #54537

   * regex.cs, compiler.cs :
    Some code to support CILCompiler.
  * regex.cs :
  Added some undocumented of MS.

svn path=/trunk/mcs/; revision=24249

mcs/class/System/System.Text.RegularExpressions/ChangeLog
mcs/class/System/System.Text.RegularExpressions/compiler.cs
mcs/class/System/System.Text.RegularExpressions/interpreter.cs
mcs/class/System/System.Text.RegularExpressions/quicksearch.cs
mcs/class/System/System.Text.RegularExpressions/regex.cs
mcs/class/System/System.Text.RegularExpressions/syntax.cs

index 00829495a59739ed1d83b2f1b8a23f2ce3df7b2a..d93214003b0d7b10b63fab99fefcdaef01db9f3b 100644 (file)
@@ -1,3 +1,14 @@
+2004-03-17  Francois Beauchemin <beauche@softhome.net>
+       * syntax.cs, interpreter.cs, quicksearch.cs, regex.cs, compiler.cs : 
+               Revised support for RigthToLeft. 
+               quicksearch has now an reverse option.          
+               This fixes bug #54537 
+       * regex.cs, compiler.cs :
+               Some code to support CILCompiler.               
+       * regex.cs : 
+               Added some undocumented of MS.
 2004-03-16  Gonzalo Paniagua Javier <gonzalo@ximian.com>
 
        * parser.cs: allow a @"\0" escape sequence. Fixes bug #54797.
index 2227568f6e8323e4ebf9d2182b145a774322f54f..8640b5d7392e4e41af0d329f47e7f5be7bd03e1d 100644 (file)
@@ -51,7 +51,11 @@ namespace System.Text.RegularExpressions {
                void EmitIn (LinkRef tail);\r
                void EmitInfo (int count, int min, int max);\r
                void EmitFastRepeat (int min, int max, bool lazy, LinkRef tail);\r
-               void EmitAnchor (int offset, LinkRef tail);\r
+               void EmitAnchor (bool reverse, int offset, LinkRef tail);\r
+\r
+               // event for the CILCompiler\r
+               void EmitBranchEnd();\r
+               void EmitAlternationEnd();\r
 \r
                LinkRef NewLink ();\r
                void ResolveLink (LinkRef link);\r
@@ -254,9 +258,9 @@ namespace System.Text.RegularExpressions {
                        EmitLink (tail);\r
                }\r
 \r
-               public void EmitAnchor (int offset, LinkRef tail) {\r
+               public void EmitAnchor (bool reverse, int offset, LinkRef tail) {\r
                        BeginLink (tail);\r
-                       Emit (OpCode.Anchor);\r
+                       Emit (OpCode.Anchor, MakeFlags(false, false, reverse, false));\r
                        EmitLink (tail);\r
                        Emit ((ushort)offset);\r
                }\r
@@ -279,6 +283,9 @@ namespace System.Text.RegularExpressions {
                                pgm[stack.OffsetAddress] = (ushort)stack.GetOffset (CurrentAddress);\r
                }\r
 \r
+               public void EmitBranchEnd(){}\r
+               public void EmitAlternationEnd(){}\r
+\r
                // private members\r
 \r
                private static OpFlags MakeFlags (bool negate, bool ignore, bool reverse, bool lazy) {\r
@@ -319,6 +326,7 @@ namespace System.Text.RegularExpressions {
                        stack.Push ();\r
                }\r
 \r
+\r
                private class PatternLinkStack : LinkStack {\r
                        public PatternLinkStack () {\r
                        }\r
@@ -375,4 +383,23 @@ namespace System.Text.RegularExpressions {
 \r
                private Stack stack;\r
        }\r
+\r
+       //Used by CILCompiler and Interpreter\r
+       internal struct Mark {\r
+               public int Start, End;\r
+               public int Previous;\r
+               \r
+               public bool IsDefined {\r
+                       get { return Start >= 0 && End >= 0; }\r
+               }\r
+               \r
+               public int Index {\r
+                       get { return Start < End ? Start : End; }\r
+               }\r
+               \r
+               public int Length {\r
+                       get { return Start < End ? End - Start : Start - End; }\r
+               }\r
+       }\r
+\r
 }\r
index 91dcf23f18fd5491437a22efc69ba1342beb5719..cdac6845865468884b7f79f5f5e636a139b3b04d 100644 (file)
@@ -63,54 +63,66 @@ namespace System.Text.RegularExpressions {
                                switch (op) {\r
                                case OpCode.Anchor: {\r
                                        int skip = program[pc + 1];\r
-\r
+                                       \r
                                        int anch_offset = program[pc + 2];\r
-                                       int anch_ptr = ptr + anch_offset;\r
-                                       int anch_end = text_end - match_min + anch_offset;      // maximum anchor position\r
+                                       bool anch_reverse = (flags & OpFlags.RightToLeft) != 0; \r
+                                       int anch_ptr = anch_reverse ?  ptr - anch_offset  : ptr + anch_offset;\r
+                                       int anch_end = text_end - match_min + anch_offset;      // maximum anchor position  \r
+                                       \r
+                                       \r
+                                       int anch_begin =  0;\r
+\r
 \r
                                        // the general case for an anchoring expression is at the bottom, however we\r
                                        // do some checks for the common cases before to save processing time. the current\r
                                        // optimizer only outputs three types of anchoring expressions: fixed position,\r
                                        // fixed substring, and no anchor.\r
 \r
-                                       OpCode anch_op = (OpCode)(program[pc + 3] & 0x00ff);\r
+                                       OpCode anch_op = (OpCode)(program[pc + 3] & 0x00ff);                                    \r
                                        if (anch_op == OpCode.Position && skip == 6) {                          // position anchor\r
                                                // Anchor\r
                                                //      Position\r
                                                //      True\r
 \r
                                                switch ((Position)program[pc + 4]) {\r
-                                               case Position.StartOfString:\r
-                                                       if (anch_ptr == 0) {\r
-                                                               ptr = 0;\r
+                                               case Position.StartOfString:                                                    \r
+                                                       if (anch_reverse || anch_offset == 0) {\r
+                                                               ptr = anch_offset;\r
                                                                if (TryMatch (ref ptr, pc + skip))\r
                                                                        goto Pass;\r
                                                        }\r
                                                        break;\r
                                                \r
                                                case Position.StartOfLine:\r
-                                                       if (anch_ptr == 0) {\r
+                                                                                                       \r
+                                                        if (anch_ptr == 0) {\r
                                                                ptr = 0;\r
                                                                if (TryMatch (ref ptr, pc + skip))\r
                                                                        goto Pass;\r
-\r
+                                                               \r
                                                                ++ anch_ptr;\r
                                                        }\r
 \r
-                                                       while (anch_ptr <= anch_end) {\r
-                                                               if (text[anch_ptr - 1] == '\n') {\r
-                                                                       ptr = anch_ptr - anch_offset;\r
+                                                       while ((anch_reverse && anch_ptr >= 0) || (!anch_reverse && anch_ptr <= anch_end)) {  \r
+                                                               if (anch_ptr == 0 || text[anch_ptr - 1] == '\n') {\r
+                                                                       if (anch_reverse)\r
+                                                                               ptr = anch_ptr == anch_end ? anch_ptr : anch_ptr + anch_offset;\r
+                                                                       else\r
+                                                                               ptr = anch_ptr == 0 ? anch_ptr : anch_ptr - anch_offset;\r
                                                                        if (TryMatch (ref ptr, pc + skip))\r
                                                                                goto Pass;\r
                                                                }\r
-\r
-                                                               ++ anch_ptr;\r
+                                                       \r
+                                                               if (anch_reverse)\r
+                                                                       -- anch_ptr;\r
+                                                               else\r
+                                                                       ++ anch_ptr;\r
                                                        }\r
                                                        break;\r
                                                \r
                                                case Position.StartOfScan:\r
-                                                       if (anch_ptr == scan_ptr) {\r
-                                                               ptr = scan_ptr - anch_offset;\r
+                                                       if (anch_ptr == scan_ptr) {                                                     \r
+                                                               ptr = anch_reverse ? scan_ptr + anch_offset : scan_ptr - anch_offset;\r
                                                                if (TryMatch (ref ptr, pc + skip))\r
                                                                        goto Pass;\r
                                                        }\r
@@ -126,36 +138,55 @@ namespace System.Text.RegularExpressions {
                                                // Anchor\r
                                                //      String\r
                                                //      True\r
+                                \r
+                                               bool reverse = ((OpFlags)program[pc + 3] & OpFlags.RightToLeft) != 0;\r
+                                               string substring = GetString (pc + 3);\r
 \r
                                                if (qs == null) {\r
                                                        bool ignore = ((OpFlags)program[pc + 3] & OpFlags.IgnoreCase) != 0;\r
-                                                       string substring = GetString (pc + 3);\r
 \r
-                                                       qs = new QuickSearch (substring, ignore);\r
+                                                       qs = new QuickSearch (substring, ignore, reverse);\r
                                                }\r
-\r
-                                               while (anch_ptr <= anch_end) {\r
-                                                       anch_ptr = qs.Search (text, anch_ptr, anch_end);\r
+                                               while ((anch_reverse && anch_ptr >= anch_begin) \r
+                                                      || (!anch_reverse && anch_ptr <= anch_end)) {\r
+\r
+                                                       if (reverse)    \r
+                                                       {\r
+                                                               anch_ptr = qs.Search (text, anch_ptr, anch_begin);\r
+                                                               if (anch_ptr != -1)\r
+                                                                       anch_ptr += substring.Length ;\r
+                                                               \r
+                                                       }\r
+                                                       else\r
+                                                               anch_ptr = qs.Search (text, anch_ptr, anch_end);\r
                                                        if (anch_ptr < 0)\r
                                                                break;\r
 \r
-                                                       ptr = anch_ptr - anch_offset;\r
+                                                       ptr = reverse ? anch_ptr + anch_offset : anch_ptr - anch_offset;\r
                                                        if (TryMatch (ref ptr, pc + skip))\r
                                                                goto Pass;\r
 \r
-                                                       ++ anch_ptr;\r
+                                                       if (reverse)\r
+                                                               anch_ptr -= 2;\r
+                                                       else \r
+                                                               ++ anch_ptr;\r
                                                }\r
                                        }\r
                                        else if (anch_op == OpCode.True) {                                      // no anchor\r
                                                // Anchor\r
                                                //      True\r
 \r
-                                               while (anch_ptr <= anch_end) {\r
+                                       \r
+                                               while ((anch_reverse && anch_ptr >= anch_begin) \r
+                                                      || (!anch_reverse && anch_ptr <= anch_end)) {\r
+\r
                                                        ptr = anch_ptr;\r
                                                        if (TryMatch (ref ptr, pc + skip))\r
                                                                goto Pass;\r
-\r
-                                                       ++ anch_ptr;\r
+                                                       if (anch_reverse)\r
+                                                               -- anch_ptr;\r
+                                                       else \r
+                                                               ++ anch_ptr;\r
                                                }\r
                                        }\r
                                        else {                                                                  // general case\r
@@ -163,17 +194,22 @@ namespace System.Text.RegularExpressions {
                                                //      <expr>\r
                                                //      True\r
 \r
-                                               while (anch_ptr <= anch_end) {\r
+                                               while ((anch_reverse && anch_ptr >= anch_begin) \r
+                                                      || (!anch_reverse && anch_ptr <= anch_end)) {\r
+\r
                                                        ptr = anch_ptr;\r
                                                        if (Eval (Mode.Match, ref ptr, pc + 3)) {\r
                                                                // anchor expression passed: try real expression at the correct offset\r
 \r
-                                                               ptr = anch_ptr - anch_offset;\r
+                                                               ptr = anch_reverse ? anch_ptr + anch_offset : anch_ptr - anch_offset;\r
                                                                if (TryMatch (ref ptr, pc + skip))\r
                                                                        goto Pass;\r
                                                        }\r
 \r
-                                                       ++ anch_ptr;\r
+                                                   if (anch_reverse)\r
+                                                               -- anch_ptr;\r
+                                                       else \r
+                                                               ++ anch_ptr;\r
                                                }\r
                                        }\r
 \r
@@ -205,7 +241,8 @@ namespace System.Text.RegularExpressions {
                                                if (ptr < 0)\r
                                                        goto Fail;\r
                                        }\r
-                                       else if (ptr + len > text_end)\r
+                                       else \r
+                                       if (ptr + len > text_end)\r
                                                goto Fail;\r
 \r
                                        pc += 2;\r
@@ -460,7 +497,16 @@ namespace System.Text.RegularExpressions {
                                                OpFlags tail_flags = (OpFlags)(tail_word & 0xff00);\r
 \r
                                                if (tail_op == OpCode.String)\r
-                                                       c1 = program[pc + 2];                           // first char of string\r
+                                               {\r
+                                                       int offset = 0;\r
+                                               \r
+                                                       if ((tail_flags & OpFlags.RightToLeft) != 0)\r
+                                                       {\r
+                                                               offset = program[pc + 1] - 1 ;\r
+                                                       }\r
+                                                         \r
+                                                       c1 = program[pc + 2 + offset];                          // first char of string\r
+                                               }\r
                                                else\r
                                                        c1 = program[pc + 1];                           // character\r
                                                \r
@@ -585,6 +631,7 @@ namespace System.Text.RegularExpressions {
                        char c = '\0';\r
                        bool negate;\r
                        bool ignore;\r
+               \r
                        do {\r
                                ushort word = program[pc];\r
                                OpCode op = (OpCode)(word & 0x00ff);\r
@@ -660,6 +707,7 @@ namespace System.Text.RegularExpressions {
                                        int i = (int)c - lo;\r
                                        if (i < 0 || i >= len << 4)\r
                                                break;\r
+                                               \r
 \r
                                        if ((program[bits + (i >> 4)] & (1 << (i & 0xf))) != 0)\r
                                                return !negate;\r
@@ -876,7 +924,7 @@ namespace System.Text.RegularExpressions {
                private int[] groups;                   // current group definitions\r
 \r
                // private classes\r
-\r
+/*\r
                private struct Mark {\r
                        public int Start, End;\r
                        public int Previous;\r
@@ -893,7 +941,7 @@ namespace System.Text.RegularExpressions {
                                get { return Start < End ? End - Start : Start - End; }\r
                        }\r
                }\r
-\r
+*/\r
                private class RepeatContext {\r
                        public RepeatContext (RepeatContext previous, int min, int max, bool lazy, int expr_pc) {\r
                                this.previous = previous;\r
index 19040e700c0b64c7998976e406efa70274cbfab7..57d5b5fb67d23cb6fc24aeff0983bdafd591a140 100644 (file)
@@ -14,14 +14,19 @@ using System;
 using System.Collections;
 
 namespace System.Text.RegularExpressions {
-       class QuickSearch {
+       public class QuickSearch {
                // simplified boyer-moore for fast substring matching
                // (for short strings, we use simple scans)
+               public QuickSearch (string str, bool ignore) 
+                       : this(str, ignore, false)
+               {
+               }
        
-               public QuickSearch (string str, bool ignore) {
+               public QuickSearch (string str, bool ignore, bool reverse) {
                        this.str = str;
                        this.len = str.Length;
                        this.ignore = ignore;
+                       this.reverse = reverse;
 
                        if (ignore)
                                str = str.ToLower ();
@@ -46,44 +51,112 @@ namespace System.Text.RegularExpressions {
                public int Search (string text, int start, int end) {
                        int ptr = start;
 
-                       // use simple scan for a single-character search string
-                       if (len == 1) {
-                               while (ptr <= end) {
-                                       if(str[0] == GetChar(text[ptr]))
-                                               return ptr;
+               
+                       if ( reverse ) 
+                       {
+                               if (start < end)
+                                       return -1;
+
+                               if ( ptr > text.Length) 
+                               {
+                                       ptr = text.Length;
+                               }
+
+                               // use simple scan for a single-character search string
+                               if (len == 1) 
+                               {
+                                       while (--ptr >= end) 
+                                       {
+                                               if(str[0] == GetChar(text[ptr]))
+                                                       return ptr ;
+                                               
+                                       }
+                                       return -1;
+                               }
+
+               
+                               if ( end < len)
+                                       end =  len - 1 ;
+
+                               ptr--;
+                               while (ptr >= end) 
+                               {
+                                       int i = len -1 ;
+                                       while (str[i] == GetChar(text[ptr - len +1 + i])) 
+                                       {
+                                               if (-- i <  0)
+                                                       return ptr - len + 1;
+                                       }
+
+                                       if (ptr > end)
+                                       {
+                                               ptr -= GetShiftDistance (text[ptr - len ]);
+                                       
+                                       }
                                        else
-                                               ptr++;
+                                               break;
                                }
-                               return -1;
+
                        }
+                       else 
+                       {
+                               // use simple scan for a single-character search string
+                               if (len == 1) 
+                               {
+                                       while (ptr <= end) 
+                                       {
+                                               if(str[0] == GetChar(text[ptr]))
+                                                       return ptr;
+                                               else
+                                                       ptr++;
+                                       }       
+                                       return -1;
+                               }
 
-                       if (end > text.Length - len)
-                               end = text.Length - len;
+                               if (end > text.Length - len)
+                                       end = text.Length - len;
 
-                       while (ptr <= end) {
-                               int i = len - 1;
-                               while (str[i] == GetChar(text[ptr + i])) {
-                                       if (-- i < 0)
-                                               return ptr;
-                               }
+                               while (ptr <= end) 
+                               {
+                                       int i = len - 1;
+                                       while (str[i] == GetChar(text[ptr + i])) 
+                                       {
+                                               if (-- i < 0)
+                                                       return ptr;
+                                       }
 
-                               if (ptr < end)
-                                       ptr += GetShiftDistance (text[ptr + len]);
-                               else
-                                       break;
+                                       if (ptr < end)
+                                               ptr += GetShiftDistance (text[ptr + len]);
+                                       else
+                                               break;
+                               }
                        }
 
                        return -1;
+                               
                }
 
-               // private
+                       // private
 
                private void SetupShiftTable () {
                        shift = new Hashtable ();
-                       for (int i = 0; i < len; ++ i) {
-                               char c = str[i];
-                               shift[GetChar(c)] = len - i;
+                       if (reverse)
+                       {
+                               for (int i = len ; i > 0; -- i) 
+                               {
+                                       char c = str[i -1];
+                                       shift[GetChar(c)] = i;
+                               }
+                       }
+                       else
+                       {
+                               for (int i = 0; i < len; ++ i) 
+                               {
+                                       char c = str[i];
+                                       shift[GetChar(c)] = len - i;
+                               }
                        }
+                       
                }
            
                private int GetShiftDistance (char c) {
@@ -101,6 +174,7 @@ namespace System.Text.RegularExpressions {
                private string str;
                private int len;
                private bool ignore;
+               private bool reverse;
 
                private Hashtable shift;
                private readonly static int THRESHOLD = 5;
index b972bea35a8b09a2388b8b42662e56b9b5470d0e..ea016aab6577081f018a037bbd3d58a9b8988278 100644 (file)
@@ -16,6 +16,9 @@ using System.Runtime.Serialization;
 using RegularExpression = System.Text.RegularExpressions.Syntax.RegularExpression;\r
 using Parser = System.Text.RegularExpressions.Syntax.Parser;\r
 \r
+using System.Diagnostics;\r
+\r
+\r
 namespace System.Text.RegularExpressions {\r
        \r
        public delegate string MatchEvaluator (Match match);\r
@@ -39,21 +42,49 @@ namespace System.Text.RegularExpressions {
                public static void CompileToAssembly\r
                        (RegexCompilationInfo[] regexes, AssemblyName aname)\r
                {\r
-                       throw new Exception ("Not implemented.");\r
+                               Regex.CompileToAssembly(regexes, aname, new CustomAttributeBuilder[] {}, null);\r
                }\r
 \r
                public static void CompileToAssembly\r
                        (RegexCompilationInfo[] regexes, AssemblyName aname,\r
                         CustomAttributeBuilder[] attribs)\r
                {\r
-                       throw new Exception ("Not implemented.");\r
+                       Regex.CompileToAssembly(regexes, aname, attribs, null);                \r
                }\r
 \r
                public static void CompileToAssembly\r
                        (RegexCompilationInfo[] regexes, AssemblyName aname,\r
                         CustomAttributeBuilder[] attribs, string resourceFile)\r
                {\r
-                       throw new Exception ("Not implemented.");\r
+                       throw new Exception ("Not fully implemented.");\r
+                       // TODO : Make use of attribs and resourceFile parameters\r
+                       /*\r
+                       AssemblyBuilder asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly (aname, AssemblyBuilderAccess.RunAndSave);\r
+                       ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule("InnerRegexModule",aname.Name);\r
+                       Parser psr = new Parser ();     \r
+                       \r
+                       System.Console.WriteLine("CompileToAssembly");\r
+                              \r
+                       for(int i=0; i < regexes.Length; i++)\r
+                               {\r
+                                       System.Console.WriteLine("Compiling expression :" + regexes[i].Pattern);\r
+                                       RegularExpression re = psr.ParseRegularExpression (regexes[i].Pattern, regexes[i].Options);\r
+                                       \r
+                                       // compile\r
+                                                                               \r
+                                       CILCompiler cmp = new CILCompiler (modBuilder, i);\r
+                                       bool reverse = (regexes[i].Options & RegexOptions.RightToLeft) !=0;\r
+                                       re.Compile (cmp, reverse);\r
+                                       cmp.Close();\r
+                                       \r
+                               }\r
+                      \r
+\r
+                       // Define a runtime class with specified name and attributes.\r
+                       TypeBuilder builder = modBuilder.DefineType("ITest");\r
+                       builder.CreateType();\r
+                       asmBuilder.Save(aname.Name);\r
+                       */\r
                }\r
                \r
                public static string Escape (string str) {\r
@@ -136,6 +167,7 @@ namespace System.Text.RegularExpressions {
 \r
                protected Regex () {\r
                        // XXX what's this constructor for?\r
+                       // : Used to compile to assembly (Custum regex inherit from Regex and use this constructor)\r
                }\r
 \r
                public Regex (string pattern) : this (pattern, RegexOptions.None) {\r
@@ -143,11 +175,11 @@ namespace System.Text.RegularExpressions {
 \r
                public Regex (string pattern, RegexOptions options) {\r
                        this.pattern = pattern;\r
-                       this.options = options;\r
+                       this.roptions = options;\r
                \r
-                       this.factory = cache.Lookup (pattern, options);\r
+                       this.machineFactory = cache.Lookup (pattern, options);\r
 \r
-                       if (this.factory == null) {\r
+                       if (this.machineFactory == null) {\r
                                // parse and install group mapping\r
 \r
                                Parser psr = new Parser ();\r
@@ -159,8 +191,8 @@ namespace System.Text.RegularExpressions {
                                \r
                                ICompiler cmp;\r
                                //if ((options & RegexOptions.Compiled) != 0)\r
-                               //      throw new Exception ("Not implemented.");\r
-                                       //cmp = new CILCompiler ();\r
+                               //      //throw new Exception ("Not implemented.");\r
+                               //      cmp = new CILCompiler ();\r
                                //else\r
                                        cmp = new PatternCompiler ();\r
 \r
@@ -168,29 +200,29 @@ namespace System.Text.RegularExpressions {
 \r
                                // install machine factory and add to pattern cache\r
 \r
-                               this.factory = cmp.GetMachineFactory ();\r
-                               this.factory.Mapping = mapping;\r
-                               cache.Add (pattern, options, this.factory);\r
+                               this.machineFactory = cmp.GetMachineFactory ();\r
+                               this.machineFactory.Mapping = mapping;\r
+                               cache.Add (pattern, options, this.machineFactory);\r
                        } else {\r
-                               this.group_count = this.factory.GroupCount;\r
-                               this.mapping = this.factory.Mapping;\r
+                               this.group_count = this.machineFactory.GroupCount;\r
+                               this.mapping = this.machineFactory.Mapping;\r
                        }\r
                }\r
 \r
                protected Regex (SerializationInfo info, StreamingContext context) :\r
                        this (info.GetString ("pattern"), \r
-                             (RegexOptions) info.GetValue ("options", typeof (RegexOptions))) {                        \r
+                             (RegexOptions) info.GetValue ("roptions", typeof (RegexOptions))) {                       \r
                }\r
 \r
 \r
                // public instance properties\r
                \r
                public RegexOptions Options {\r
-                       get { return options; }\r
+                       get { return roptions; }\r
                }\r
 \r
                public bool RightToLeft {\r
-                       get { return (options & RegexOptions.RightToLeft) != 0; }\r
+                       get { return (roptions & RegexOptions.RightToLeft) != 0; }\r
                }\r
 \r
                // public instance methods\r
@@ -231,7 +263,10 @@ namespace System.Text.RegularExpressions {
                // match methods\r
                \r
                public bool IsMatch (string input) {\r
-                       return IsMatch (input, 0);\r
+                       if (RightToLeft)\r
+                               return IsMatch (input, input.Length);\r
+                       else\r
+                               return IsMatch (input, 0);\r
                }\r
 \r
                public bool IsMatch (string input, int startat) {\r
@@ -239,19 +274,27 @@ namespace System.Text.RegularExpressions {
                }\r
 \r
                public Match Match (string input) {\r
-                       return Match (input, 0);\r
+                       if (RightToLeft)\r
+                               return Match (input, input.Length);\r
+                       else\r
+                               return Match (input, 0);\r
                }\r
 \r
                public Match Match (string input, int startat) {\r
+       \r
                        return CreateMachine ().Scan (this, input, startat, input.Length);\r
                }\r
 \r
                public Match Match (string input, int startat, int length) {\r
+       \r
                        return CreateMachine ().Scan (this, input, startat, startat + length);\r
                }\r
 \r
                public MatchCollection Matches (string input) {\r
-                       return Matches (input, 0);\r
+                       if (RightToLeft)\r
+                               return Matches (input, input.Length);\r
+                       else\r
+                               return Matches (input, 0);\r
                }\r
 \r
                public MatchCollection Matches (string input, int startat) {\r
@@ -268,11 +311,17 @@ namespace System.Text.RegularExpressions {
                // replace methods\r
 \r
                public string Replace (string input, MatchEvaluator evaluator) {\r
-                       return Replace (input, evaluator, Int32.MaxValue, 0);\r
+                       if (RightToLeft)                        \r
+                               return Replace (input, evaluator, Int32.MaxValue, input.Length);\r
+                       else\r
+                               return Replace (input, evaluator, Int32.MaxValue, 0);\r
                }\r
 \r
                public string Replace (string input, MatchEvaluator evaluator, int count) {\r
-                       return Replace (input, evaluator, count, 0);\r
+                       if (RightToLeft)\r
+                               return Replace (input, evaluator, count, input.Length);\r
+                       else\r
+                               return Replace (input, evaluator, count, 0);\r
                }\r
 \r
                public string Replace (string input, MatchEvaluator evaluator, int count, int startat)\r
@@ -294,11 +343,17 @@ namespace System.Text.RegularExpressions {
                }\r
 \r
                public string Replace (string input, string replacement) {\r
-                       return Replace (input, replacement, Int32.MaxValue, 0);\r
+                       if (RightToLeft)\r
+                               return Replace (input, replacement, Int32.MaxValue, input.Length);\r
+                       else\r
+                               return Replace (input, replacement, Int32.MaxValue, 0);\r
                }\r
 \r
                public string Replace (string input, string replacement, int count) {\r
-                       return Replace (input, replacement, count, 0);\r
+                       if (RightToLeft)                        \r
+                               return Replace (input, replacement, count, input.Length);\r
+                       else    \r
+                               return Replace (input, replacement, count, 0);\r
                }\r
 \r
                public string Replace (string input, string replacement, int count, int startat) {\r
@@ -309,11 +364,17 @@ namespace System.Text.RegularExpressions {
                // split methods\r
 \r
                public string[] Split (string input) {\r
-                       return Split (input, Int32.MaxValue, 0);\r
+                       if (RightToLeft)        \r
+                               return Split (input, Int32.MaxValue, input.Length);\r
+                       else\r
+                               return Split (input, Int32.MaxValue, 0);\r
                }\r
 \r
                public string[] Split (string input, int count) {\r
-                       return Split (input, count, 0);\r
+                       if (RightToLeft)                                \r
+                               return Split (input, count, input.Length);\r
+                       else\r
+                               return Split (input, count, 0);\r
                }\r
 \r
                public string[] Split (string input, int count, int startat) {\r
@@ -327,23 +388,53 @@ namespace System.Text.RegularExpressions {
                                if (!m.Success)\r
                                        break;\r
                        \r
-                               splits.Add (input.Substring (ptr, m.Index - ptr));\r
+                               if (RightToLeft)\r
+                                       splits.Add (input.Substring (m.Index + m.Length , ptr - m.Index - m.Length ));\r
+                               else\r
+                                       splits.Add (input.Substring (ptr, m.Index - ptr));\r
+                                       \r
                                int gcount = m.Groups.Count;\r
                                for (int gindex = 1; gindex < gcount; gindex++) {\r
                                        Group grp = m.Groups [gindex];\r
                                        splits.Add (input.Substring (grp.Index, grp.Length));\r
                                }\r
 \r
-                               ptr = m.Index + m.Length;\r
+                               if (RightToLeft)\r
+                                       ptr = m.Index; \r
+                               else\r
+                                       ptr = m.Index + m.Length;\r
+                                       \r
                        }\r
 \r
-                       if (ptr <= input.Length) {\r
-                               splits.Add (input.Substring (ptr));\r
+                       if (RightToLeft) {\r
+                               if ( ptr >= 0) {\r
+                                               splits.Add (input.Substring(0, ptr));\r
+                               }\r
+                       }                               \r
+                       else {\r
+                               if (ptr <= input.Length) {\r
+                                               splits.Add (input.Substring (ptr));\r
+                               }\r
+                               \r
                        }\r
 \r
                        return (string []) splits.ToArray (typeof (string));\r
                }\r
 \r
+               // MS undocummented method\r
+                               \r
+               protected void InitializeReferences() {\r
+                       throw new Exception ("Not implemented.");\r
+               }\r
+               \r
+               protected bool UseOptionC(){\r
+                       throw new Exception ("Not implemented.");\r
+               }\r
+\r
+               protected bool UseOptionR(){\r
+                       throw new Exception ("Not implemented.");\r
+               }\r
+\r
                // object methods\r
                \r
                public override string ToString () {\r
@@ -353,7 +444,7 @@ namespace System.Text.RegularExpressions {
                // ISerializable interface\r
                public virtual void GetObjectData (SerializationInfo info, StreamingContext context) {\r
                        info.AddValue ("pattern", this.ToString (), typeof (string));\r
-                       info.AddValue ("options", this.Options, typeof (RegexOptions));\r
+                       info.AddValue ("roptions", this.Options, typeof (RegexOptions));\r
                }\r
 \r
                // internal\r
@@ -365,15 +456,25 @@ namespace System.Text.RegularExpressions {
                // private\r
 \r
                private IMachine CreateMachine () {\r
-                       return factory.NewInstance ();\r
+                       return machineFactory.NewInstance ();\r
                }\r
 \r
-               protected internal string pattern;\r
-               private RegexOptions options;\r
-\r
-               private IMachineFactory factory;\r
+               private IMachineFactory machineFactory;\r
                private IDictionary mapping;\r
                private int group_count;\r
+\r
+               \r
+               // protected members\r
+\r
+               protected internal string pattern;\r
+               protected internal RegexOptions roptions;\r
+               \r
+               // MS undocumented members\r
+               protected internal System.Collections.Hashtable capnames;\r
+               protected internal System.Collections.Hashtable cap;\r
+               protected internal int capsize;\r
+               protected internal string[] caplist;\r
+               protected internal RegexRunnerFactory factory;\r
        }\r
 \r
        [Serializable]\r
index e503f3edcd8cd4cd245b44283307ebfa6f400822..46f5bd899dda90dd931eaf6346869dae9cb6ee33 100644 (file)
@@ -43,7 +43,7 @@ namespace System.Text.RegularExpressions.Syntax {
                        return -1;\r
                }\r
 \r
-               public virtual AnchorInfo GetAnchorInfo () {\r
+               public virtual AnchorInfo GetAnchorInfo (bool reverse) {\r
                        return new AnchorInfo (this, GetFixedWidth ());\r
                }\r
 \r
@@ -130,7 +130,7 @@ namespace System.Text.RegularExpressions.Syntax {
                        }\r
                }\r
 \r
-               public override AnchorInfo GetAnchorInfo () {\r
+               public override AnchorInfo GetAnchorInfo (bool reverse) {\r
                        int ptr;\r
                        int width = GetFixedWidth ();\r
 \r
@@ -140,8 +140,16 @@ namespace System.Text.RegularExpressions.Syntax {
                        // accumulate segments\r
 \r
                        ptr = 0;\r
-                       foreach (Expression e in Expressions) {\r
-                               AnchorInfo info = e.GetAnchorInfo ();\r
+                       //foreach (Expression e in Expressions) {\r
+                       int count = Expressions.Count;\r
+                       for (int i = 0; i < count; ++ i) {\r
+                               Expression e;\r
+                               if (reverse)\r
+                                       e = Expressions [count - i - 1];\r
+                               else\r
+                                       e = Expressions [i];            \r
+                               \r
+                               AnchorInfo info = e.GetAnchorInfo (reverse);\r
                                infos.Add (info);\r
 \r
                                if (info.IsPosition)\r
@@ -170,20 +178,40 @@ namespace System.Text.RegularExpressions.Syntax {
 \r
                        if (!longest.IsEmpty) {\r
                                string str = "";\r
+                               ArrayList strs = new ArrayList();\r
                                bool ignore = false;\r
 \r
                                ptr = 0;\r
-                               foreach (AnchorInfo info in infos) {\r
+                               \r
+                               //foreach (AnchorInfo info in infos) {\r
+                               for (int i = 0; i < infos.Count; ++ i) {\r
+                                       AnchorInfo info;\r
+\r
+                                       info = (AnchorInfo)infos[i];            \r
+                                       \r
                                        if (info.IsSubstring && longest.Contains (info.GetInterval (ptr))) {\r
-                                               str += info.Substring;  // TODO mark subexpressions\r
+                                               //str += info.Substring;        // TODO mark subexpressions\r
+                                               strs.Add(info.Substring);\r
                                                ignore |= info.IgnoreCase;\r
                                        }\r
 \r
-                                       if (info.IsUnknownWidth)\r
-                                               break;\r
-\r
-                                       ptr += info.Width;\r
+                                       \r
+                                               if (info.IsUnknownWidth)                                                        \r
+                                                       break;\r
+                                       \r
+                                               ptr += info.Width;\r
+                               }       \r
+                                       \r
+                               for (int i = 0; i< strs.Count; ++i)\r
+                               {\r
+                                       if (reverse)\r
+                                               str += strs [strs.Count - i - 1];\r
+                                       else\r
+                                               str += strs [i];\r
+                                                       \r
+                                       \r
                                }\r
+                       \r
 \r
                                return new AnchorInfo (this, longest.low, width, str, ignore);\r
                        }\r
@@ -220,12 +248,12 @@ namespace System.Text.RegularExpressions.Syntax {
 \r
                        // anchoring expression\r
 \r
-                       AnchorInfo info = GetAnchorInfo ();\r
-                       if (reverse)\r
-                               info = new AnchorInfo (this, GetFixedWidth ()); // FIXME\r
+                       AnchorInfo info = GetAnchorInfo (reverse);\r
+                       //if (reverse)\r
+                       //      info = new AnchorInfo (this, GetFixedWidth ()); // FIXME\r
 \r
                        LinkRef pattern = cmp.NewLink ();\r
-                       cmp.EmitAnchor (info.Offset, pattern);\r
+                       cmp.EmitAnchor (reverse, info.Offset, pattern);\r
 \r
                        if (info.IsPosition)\r
                                cmp.EmitPosition (info.Position);\r
@@ -385,12 +413,12 @@ namespace System.Text.RegularExpressions.Syntax {
                                max = max * this.max;\r
                }\r
 \r
-               public override AnchorInfo GetAnchorInfo () {\r
+               public override AnchorInfo GetAnchorInfo (bool reverse) {\r
                        int width = GetFixedWidth ();\r
                        if (Minimum == 0)\r
                                return new AnchorInfo (this, width);\r
                        \r
-                       AnchorInfo info = Expression.GetAnchorInfo ();\r
+                       AnchorInfo info = Expression.GetAnchorInfo (reverse);\r
                        if (info.IsPosition)\r
                                return new AnchorInfo (this, info.Offset, width, info.Position);\r
                        \r
@@ -524,7 +552,7 @@ namespace System.Text.RegularExpressions.Syntax {
                        \r
                        // test expression: lookahead / lookbehind\r
 \r
-                       TestExpression.Compile (cmp, reverse ^ this.reverse);\r
+                       TestExpression.Compile (cmp, this.reverse);\r
                        cmp.EmitTrue ();\r
 \r
                        // target expressions\r
@@ -587,18 +615,21 @@ namespace System.Text.RegularExpressions.Syntax {
                }\r
 \r
                public override void Compile (ICompiler cmp, bool reverse) {\r
-                       LinkRef next = cmp.NewLink ();\r
+                       //                      LinkRef next = cmp.NewLink ();\r
                        LinkRef tail = cmp.NewLink ();\r
                \r
                        foreach (Expression e in Alternatives) {\r
+                               LinkRef next = cmp.NewLink ();\r
                                cmp.EmitBranch (next);\r
                                e.Compile (cmp, reverse);\r
                                cmp.EmitJump (tail);\r
                                cmp.ResolveLink (next);\r
+                               cmp.EmitBranchEnd();\r
                        }\r
 \r
                        cmp.EmitFalse ();\r
                        cmp.ResolveLink (tail);\r
+                       cmp.EmitAlternationEnd();\r
                }\r
 \r
                public override void GetWidth (out int min, out int max) {\r
@@ -647,7 +678,7 @@ namespace System.Text.RegularExpressions.Syntax {
                        min = max = str.Length;\r
                }\r
 \r
-               public override AnchorInfo GetAnchorInfo () {\r
+               public override AnchorInfo GetAnchorInfo (bool reverse) {\r
                        return new AnchorInfo (this, 0, str.Length, str, ignore);\r
                }\r
 \r
@@ -681,7 +712,7 @@ namespace System.Text.RegularExpressions.Syntax {
                        return false;\r
                }\r
 \r
-               public override AnchorInfo GetAnchorInfo () {\r
+               public override AnchorInfo GetAnchorInfo (bool revers) {\r
                        switch (pos) {\r
                        case Position.StartOfString: case Position.StartOfLine: case Position.StartOfScan:\r
                                return new AnchorInfo (this, 0, 0, pos);\r
@@ -816,7 +847,6 @@ namespace System.Text.RegularExpressions.Syntax {
 \r
                public override void Compile (ICompiler cmp, bool reverse) {\r
                        // create the meta-collection\r
-\r
                        IntervalCollection meta =\r
                                intervals.GetMetaCollection (new IntervalCollection.CostDelegate (GetIntervalCost));\r
 \r
@@ -836,6 +866,7 @@ namespace System.Text.RegularExpressions.Syntax {
                        LinkRef tail = cmp.NewLink ();\r
                        if (count > 1)\r
                                cmp.EmitIn (tail);\r
+                               \r
 \r
                        // emit categories\r
 \r
@@ -1004,3 +1035,4 @@ namespace System.Text.RegularExpressions.Syntax {
                }\r
        }\r
 }\r
+\r