Beispiel #1
0
        private bool Match(RubyRegex /*!*/ pattern, bool currentPositionOnly, bool advancePosition)
        {
            Match match = pattern.Match(_scanString, _currentPosition);

            _lastMatch          = null;
            _lastMatchingGroups = null;
            _foundPosition      = 0;
            if (!match.Success)
            {
                return(false);
            }
            if (currentPositionOnly && match.Index != _currentPosition)
            {
                return(false);
            }
            int length = (match.Index - _currentPosition) + match.Length;

            _foundPosition      = match.Index;
            _previousPosition   = _currentPosition;
            _lastMatch          = _scanString.GetSlice(_foundPosition, match.Length);
            _lastMatchingGroups = match.Groups;
            if (advancePosition)
            {
                _currentPosition += length;
            }
            return(true);
        }
Beispiel #2
0
        private bool Match(RubyRegex /*!*/ pattern, bool currentPositionOnly, bool advancePosition)
        {
            // TODO: repeated calls on the same ScanString can be optimized:
            MatchData match = pattern.Match(null, _scanString, _currentPosition, false);

            _lastMatch          = null;
            _lastMatchingGroups = null;
            _foundPosition      = 0;
            if (match == null)
            {
                return(false);
            }
            if (currentPositionOnly && match.Index != _currentPosition)
            {
                return(false);
            }
            int length = (match.Index - _currentPosition) + match.Length;

            _foundPosition      = match.Index;
            _previousPosition   = _currentPosition;
            _lastMatch          = _scanString.GetSlice(_foundPosition, match.Length);
            _lastMatchingGroups = match;
            if (advancePosition)
            {
                _currentPosition += length;
            }
            return(true);
        }
 public static Node /*!*/ ToYaml(RubyRegex /*!*/ self, [NotNull] RubyRepresenter /*!*/ rep)
 {
     return(rep.Scalar(
                rep.GetTagUri(self),
                self.Inspect().ToAsciiString(),
                ScalarQuotingStyle.None
                ));
 }
Beispiel #4
0
 public static Node /*!*/ ToYaml(RubyRegex /*!*/ self, [NotNull] RubyRepresenter /*!*/ rep)
 {
     return(rep.Scalar(
                rep.GetTagUri(self),
                self.Inspect().ToAsciiString(rep.Context.RubyOptions.Compatibility < RubyCompatibility.Ruby19),
                ScalarQuotingStyle.None
                ));
 }
Beispiel #5
0
 public static int?Exist(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern)
 {
     if (!self.Match(pattern, false, false))
     {
         return(null);
     }
     return(self.FoundPosition + self.LastMatch.Length);
 }
Beispiel #6
0
 public static int?Match(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern)
 {
     if (!self.Match(pattern, true, false))
     {
         return(null);
     }
     return(self.LastMatch.GetLength());
 }
Beispiel #7
0
        public static int?SkipUntil(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern)
        {
            bool match = self.Match(pattern, false, true);

            if (!match)
            {
                return(null);
            }
            return(self.CurrentPosition - self.PreviousPosition);
        }
Beispiel #8
0
        public static object AddDomainType(RubyContext /*!*/ context, BlockParam /*!*/ block, RubyModule /*!*/ self,
                                           MutableString /*!*/ domainAndDate, RubyRegex /*!*/ typeRegex)
        {
            if (block == null)
            {
                throw RubyExceptions.NoBlockGiven();
            }
            MutableString tag = MutableString.Create("tag:").
                                Append(domainAndDate).Append(":").
                                Append(typeRegex.GetPattern());

            RubyConstructor.AddExternalMultiConstructor(tag.ConvertToString(), block);
            return(null);
        }
Beispiel #9
0
        public static object AddDomainType(RubyContext/*!*/ context, BlockParam/*!*/ block, RubyModule/*!*/ self, 
            MutableString/*!*/ domainAndDate, RubyRegex/*!*/ typeRegex)
        {
            if (block == null) {
                throw RubyExceptions.NoBlockGiven();
            }

            MutableString tag = MutableString.CreateMutable(typeRegex.Encoding).
                Append("tag:").
                Append(domainAndDate).
                Append(':').
                Append(typeRegex.Pattern);

            RubyConstructor.AddExternalMultiConstructor(tag.ConvertToString(), block);
            return null;
        }
Beispiel #10
0
        public static object ScanFull(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern, bool advancePointer, bool returnString)
        {
            bool match = self.Match(pattern, true, advancePointer);

            if (match)
            {
                if (returnString)
                {
                    return(MutableString.Create(self.LastMatch));
                }
                else
                {
                    return(ScriptingRuntimeHelpers.Int32ToObject(self.LastMatch.Length));
                }
            }
            return(null);
        }
Beispiel #11
0
        public static object ScanFull(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern, bool advance_pointer_p, bool return_string_p)
        {
            bool   match  = self.Match(pattern, true, advance_pointer_p);
            object result = null;

            if (match)
            {
                if (return_string_p)
                {
                    result = MutableString.Create(self.LastMatch);
                }
                else
                {
                    result = self.LastMatch.Length;
                }
            }
            return(result);
        }
Beispiel #12
0
        public static object SearchFull(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern, bool advancePointer, bool returnString)
        {
            bool match = self.Match(pattern, false, advancePointer);

            if (match)
            {
                int length = self.LastMatch.Length + (self.FoundPosition - self.PreviousPosition);
                if (returnString)
                {
                    return(self.ScanString.GetSlice(self.PreviousPosition, length));
                }
                else
                {
                    return(ScriptingRuntimeHelpers.Int32ToObject(length));
                }
            }
            return(null);
        }
Beispiel #13
0
        public static object SearchFull(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern, bool advance_pointer_p, bool return_string_p)
        {
            bool   match  = self.Match(pattern, false, advance_pointer_p);
            object result = null;

            if (match)
            {
                int length = self.LastMatch.Length + (self.FoundPosition - self.PreviousPosition);
                if (return_string_p)
                {
                    result = self.ScanString.GetSlice(self.PreviousPosition, length);
                }
                else
                {
                    result = length;
                }
            }
            return(result);
        }
Beispiel #14
0
        public void RegexEscape1()
        {
            string[] patterns = new string[] {
                @"",
                @"",

                @"\",
                @"\\",

                @"(*)",
                @"\(\*\)",

                "$_^_|_[_]_(_)_\\_._#_-_{_}_*_+_?_\t_\n_\r_\f_\v_\a_\b",
                @"\$_\^_\|_\[_\]_\(_\)_\\_\._\#_\-_\{_\}_\*_\+_\?_\t_\n_\r_\f_" + "\v_\a_\b"
            };

            for (int i = 0; i < patterns.Length; i += 2)
            {
                string expected = patterns[i + 1];
                string actual   = RubyRegex.Escape(patterns[i]);
                Assert(actual == expected);
            }
        }
Beispiel #15
0
        public void RegexEncoding1() {
            MatchData m;
            // the k-coding of the pattern string is irrelevant:
            foreach (var pe in new[] { RubyEncoding.KCodeSJIS, RubyEncoding.KCodeUTF8, RubyEncoding.Binary }) {
                var p = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, (byte)'{', (byte)'2', (byte)'}' }, pe);

                var r = new RubyRegex(p, RubyRegexOptions.NONE);
                var rs = new RubyRegex(p, RubyRegexOptions.SJIS);

                // the k-coding of the string is irrelevant:
                foreach (var se in new[] { RubyEncoding.KCodeSJIS, RubyEncoding.KCodeUTF8, RubyEncoding.Binary }) {
                    var s = MutableString.CreateBinary(new byte[] { 0x82, 0xa0,  0xa0 }, se);
                    var t = MutableString.CreateBinary(new byte[] { 0x82, 0xa0,  0xa0,  0x82, 0xa0,  0xa0, 0xff }, se);
                    var u = MutableString.CreateBinary(new byte[] { 0x82, 0xa0,  0x82, 0xa0,  0x82, 0xa0 }, se);

                    // /あ{2}/ does not match "あ\xa0"
                    m = r.Match(RubyEncoding.KCodeSJIS, s);
                    Assert(m == null);

                    // /\x82\xa0{2}/ matches "[ \x82\xa0\xa0 ] \x82\xa0\xa0\xff"
                    m = r.Match(null, s);
                    Assert(m != null && m.Index == 0);

                    // /\x82\xa0{2}/ matches "\x82\xa0\xa0 [ \x82\xa0\xa0 ] \xff" starting from byte #1:
                    m = r.Match(null, t, 1, false);
                    Assert(m != null && m.Index == 3 && m.Length == 3);

                    // /あ{2}/s does not match "あ\xa0", current KCODE is ignored
                    m = rs.Match(null, s);
                    Assert(m == null);

                    // /あ{2}/s does not match "あ\xa0", current KCODE is ignored
                    m = rs.Match(RubyEncoding.KCodeUTF8, s);
                    Assert(m == null);

                    // /あ{2}/s matches "ああ\xff", current KCODE is ignored
                    m = rs.Match(RubyEncoding.KCodeUTF8, u, 2, false);
                    Assert(m != null && m.Index == 2 && m.Length == 4);


                    // /あ{2}/ does not match "あ\xa0あ\xa0"
                    m = r.LastMatch(RubyEncoding.KCodeSJIS, t);
                    Assert(m == null);

                    // /\x82\xa0{2}/ matches "\x82\xa0\xa0 [ \x82\xa0\xa0 ] \xff"
                    m = r.LastMatch(null, t);
                    Assert(m != null && m.Index == 3);

                    // /あ{2}/s does not match "あ\xa0あ\xa0", current KCODE is ignored
                    m = rs.LastMatch(null, t);
                    Assert(m == null);

                    // /あ{2}/s does not match "あ\xa0あ\xa0", current KCODE is ignored
                    m = rs.LastMatch(RubyEncoding.KCodeUTF8, t);
                    Assert(m == null);
                }
            }
        }
Beispiel #16
0
        public void RegexEncoding2() {
            var SJIS = RubyEncoding.KCodeSJIS.StrictEncoding;

            // 1.9 encodings:
            var invalidUtf8 = MutableString.CreateBinary(new byte[] { 0x80 }, RubyEncoding.UTF8);
            AssertExceptionThrown<ArgumentException>(() => new RubyRegex(invalidUtf8, RubyRegexOptions.NONE));

            // LastMatch

            MatchData m;
            var u = MutableString.CreateBinary(SJIS.GetBytes("あああ"), RubyEncoding.KCodeSJIS);
            var p = MutableString.CreateBinary(SJIS.GetBytes("あ{2}"), RubyEncoding.KCodeSJIS);

            var rs = new RubyRegex(p, RubyRegexOptions.SJIS);

            // /あ{2}/ matches "あああ", the resulting index is in bytes:
            m = rs.LastMatch(null, u);
            Assert(m != null && m.Index == 2);

            rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("あ")), RubyRegexOptions.SJIS);

            // "start at" in the middle of a character:
            m = rs.LastMatch(null, u, 0);
            Assert(m != null && m.Index == 0);

            m = rs.LastMatch(null, u, 1);
            Assert(m != null && m.Index == 0);

            m = rs.LastMatch(null, u, 2);
            Assert(m != null && m.Index == 2);

            m = rs.LastMatch(null, u, 3);
            Assert(m != null && m.Index == 2);

            // Split
            
            u = MutableString.CreateBinary(SJIS.GetBytes("あちあちあ"), RubyEncoding.UTF8);
            rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("ち")), RubyRegexOptions.SJIS);
            var parts = rs.Split(null, u);
            Assert(parts.Length == 3);
            foreach (var part in parts) {
                Assert(part.Encoding == RubyEncoding.KCodeSJIS);
                Assert(part.ToString() == "あ");
            }

            // groups

            rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("ち(a(あ+)(b+))+あ")), RubyRegexOptions.SJIS);
            u = MutableString.CreateBinary(SJIS.GetBytes("ちaああbaあbbbあ"));

            m = rs.Match(null, u);
            Assert(m.GroupCount == 4);

            int s, l;
            Assert(m.GetGroupStart(0) == (s = 0));
            Assert(m.GetGroupLength(0) == (l = u.GetByteCount()));
            Assert(m.GetGroupEnd(0) == s + l);

            // the group has 2 captures, the last one is its value:
            Assert(m.GetGroupStart(1) == (s = SJIS.GetByteCount("ちaああb")));
            Assert(m.GetGroupLength(1) == (l = SJIS.GetByteCount("aあbbb")));
            Assert(m.GetGroupEnd(1) == s + l);

            // the group has 2 captures, the last one is its value:
            Assert(m.GetGroupStart(2) == (s = SJIS.GetByteCount("ちaああba")));
            Assert(m.GetGroupLength(2) == (l = SJIS.GetByteCount("あ")));
            Assert(m.GetGroupEnd(2) == s + l);

            // the group has 2 captures, the last one is its value:
            Assert(m.GetGroupStart(3) == (s = SJIS.GetByteCount("ちaああbaあ")));
            Assert(m.GetGroupLength(3) == (l = SJIS.GetByteCount("bbb")));
            Assert(m.GetGroupEnd(3) == s + l);
        }
Beispiel #17
0
        private static object BlockReplaceInPlace(RubyScope/*!*/ scope, BlockParam/*!*/ block, MutableString/*!*/ self, 
            RubyRegex/*!*/ pattern, bool replaceAll) {

            object blockResult;

            uint version = self.Version;

            // prepare replacement in a builder:
            MutableString builder;
            if (replaceAll ?
                BlockReplaceAll(scope, self, block, pattern, out blockResult, out builder) :
                BlockReplaceFirst(scope, self, block, pattern, out blockResult, out builder)) {

                // block jumped:
                return blockResult;
            }

            // unsuccessful match:
            if (builder == null) {
                return null;
            }

            RequireNoVersionChange(version, self);

            if (self.IsFrozen) {
                throw new RuntimeError("string frozen");
            }

            // replace content of self with content of the builder:
            self.Replace(0, self.Length, builder);
            return self.TaintBy(builder);
        }
Beispiel #18
0
 public static MutableString CheckUntil(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern)
 {
     return(SearchFull(self, pattern, false, true) as MutableString);
 }
Beispiel #19
0
        private static MutableString ReplaceFirst(RubyScope/*!*/ scope, MutableString/*!*/ input, MutableString/*!*/ replacement, RubyRegex/*!*/ pattern) {
            MatchData match = RegexpOps.Match(scope, pattern, input);
            if (match == null || !match.Success) {
                return null;
            }

            MutableString result = input.CreateInstance().TaintBy(input).TaintBy(replacement);
            
            // prematch:
            result.Append(input, 0, match.Index);

            AppendReplacementExpression(input, match, result, replacement);

            // postmatch:
            int offset = match.Index + match.Length;
            result.Append(input, offset, input.Length - offset);

            return result;
        }
Beispiel #20
0
        public static object BlockReplaceFirst(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, 
            [NotNull]MutableString matchString) {

            object blockResult;
            MutableString result;
            var regex = new RubyRegex(Regex.Escape(matchString.ToString()), RubyRegexOptions.NONE);

            return BlockReplaceFirst(scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone());
        }
Beispiel #21
0
        public void MutableString_IndexRegex1() {
            var SJIS = RubyEncoding.GetRubyEncoding(RubyEncoding.CodePageSJIS);
            var sjis = new byte[] { 0x82, 0xA0 };
            var u12345 = new byte[] { 0xF0, 0x92, 0x8D, 0x85 }; // \u{12345} in UTF-8
            var invalid = MutableString.CreateBinary(new byte[] { 0x80 }, RubyEncoding.UTF8);
            int i;
            MutableString a;
            RubyRegex r;
            RubyScope scope = new RubyTopLevelScope(Context);

            // incompatible encodings:
            a = MutableString.CreateBinary(sjis, SJIS);
            r = new RubyRegex(MutableString.CreateBinary(u12345, RubyEncoding.UTF8));
            AssertExceptionThrown<EncodingCompatibilityError>(() => MutableStringOps.Index(scope, a, r, 0));

            // invalid character:
            AssertExceptionThrown<ArgumentException>(() => MutableStringOps.Index(scope, invalid, r, 0));

            // returns character index:
            i = (int)MutableStringOps.Index(
                scope,
                MutableString.CreateMutable("aαb", RubyEncoding.UTF8),
                new RubyRegex(MutableString.CreateMutable("b", SJIS)),
                0
            );
            Assert(i == 2);

            // "start at" counts chars in 1.9, returns character index
            i = (int)MutableStringOps.Index(
                scope,
                MutableString.CreateMutable("αabbba", RubyEncoding.UTF8),
                new RubyRegex(MutableString.CreateAscii("a")),
                2
            );
            Assert(i == 5);

            // "start at" counts bytes in 1.8, returns byte index (regardless of KCODE)
            i = (int)MutableStringOps.Index(
                scope,
                MutableString.CreateBinary(Encoding.UTF8.GetBytes("αa"), RubyEncoding.Binary),
                new RubyRegex(MutableString.CreateAscii("a"), RubyRegexOptions.UTF8),
                2
            );
            Assert(i == 2);

            // returns byte index for k-coded strings:
            i = (int)MutableStringOps.Index(
                scope,
                MutableString.CreateMutable("αaβb", RubyEncoding.KCodeUTF8),
                new RubyRegex(MutableString.CreateMutable("a", RubyEncoding.KCodeSJIS)),
                0
            );
            Assert(i == 2);

            // returns byte index for k-coded strings:
            i = (int)MutableStringOps.Index(
                scope,
                MutableString.CreateMutable("αabbba", RubyEncoding.KCodeUTF8),
                new RubyRegex(MutableString.CreateAscii("a")),
                2
            );
            Assert(i == 2);

            // uses the current KCODE for match:
            a = MutableString.CreateBinary(new byte[] { 0x82, 0xa1, 0x82, 0xa0, 0x82, 0xa0 }, RubyEncoding.Binary);
            r = new RubyRegex(MutableString.CreateBinary(new byte[] { 0x82, 0xa0, (byte)'{', (byte)'2', (byte)'}' }, RubyEncoding.Binary));

            Context.KCode = RubyEncoding.KCodeSJIS;
            Assert((int)MutableStringOps.Index(scope, a, r, 0) == 2);

            Context.KCode = null;
            Assert(MutableStringOps.Index(scope, a, r, 0) == null);

            // invalid characters:
            a = MutableString.CreateBinary(new byte[] { 0x82, 0x82, 0xa0, 0xa0, 0x82 }, RubyEncoding.Binary); // invalid
            r = new RubyRegex(MutableString.CreateBinary(new byte[] { 0x82, 0xa0, (byte)'{', (byte)'2', (byte)'}' }, RubyEncoding.Binary)); // valid

            Context.KCode = RubyEncoding.KCodeSJIS;
            Assert(MutableStringOps.Index(scope, a, r, 0) == null);

            Context.KCode = null;
            Assert((int)MutableStringOps.Index(scope, a, r, 0) == 1);
        }
Beispiel #22
0
 public static object /*!*/ Scan(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern)
 {
     return(ScanFull(self, pattern, true, true));
 }
Beispiel #23
0
 private Subclass(RubyRegex.Subclass/*!*/ regex)
     : base(regex) {
     _class = regex._class;
 }
Beispiel #24
0
        public static object BlockReplaceAll(ConversionStorage<MutableString>/*!*/ tosConversion, 
            RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, 
            [NotNull]MutableString matchString) {

            object blockResult;
            MutableString result;
            // TODO:
            var regex = new RubyRegex(MutableString.CreateMutable(Regex.Escape(matchString.ToString()), matchString.Encoding), RubyRegexOptions.NONE);

            self.TrackChanges();
            object r = BlockReplaceAll(tosConversion, scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone());
            RequireNoVersionChange(self);
            return r;
        }
Beispiel #25
0
 public static Node/*!*/ ToYaml(RubyRegex/*!*/ self, [NotNull]RubyRepresenter/*!*/ rep) {
     return rep.Scalar(self, rep.Context.Inspect(self));
 }
Beispiel #26
0
        public void RegexEncoding1()
        {
            MatchData m;

            // the k-coding of the pattern string is irrelevant:
            foreach (var pe in new[] { RubyEncoding.Binary })
            {
                var p = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, (byte)'{', (byte)'2', (byte)'}' }, pe);

                var r  = new RubyRegex(p, RubyRegexOptions.NONE);
                var rs = new RubyRegex(p, RubyRegexOptions.SJIS);

                // the k-coding of the string is irrelevant:
                foreach (var se in new[] { RubyEncoding.Binary })
                {
                    var s = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, 0xa0 }, se);
                    var t = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, 0xa0, 0x82, 0xa0, 0xa0, 0xff }, se);
                    var u = MutableString.CreateBinary(new byte[] { 0x82, 0xa0, 0x82, 0xa0, 0x82, 0xa0 }, se);

                    // /あ{2}/ does not match "あ\xa0"
                    m = r.Match(RubyEncoding.KCodeSJIS, s);
                    Assert(m == null);

                    // /\x82\xa0{2}/ matches "[ \x82\xa0\xa0 ] \x82\xa0\xa0\xff"
                    m = r.Match(null, s);
                    Assert(m != null && m.Index == 0);

                    // /\x82\xa0{2}/ matches "\x82\xa0\xa0 [ \x82\xa0\xa0 ] \xff" starting from byte #1:
                    m = r.Match(null, t, 1, false);
                    Assert(m != null && m.Index == 3 && m.Length == 3);

                    // /あ{2}/s does not match "あ\xa0", current KCODE is ignored
                    m = rs.Match(null, s);
                    Assert(m == null);

                    // /あ{2}/s does not match "あ\xa0", current KCODE is ignored
                    m = rs.Match(RubyEncoding.KCodeUTF8, s);
                    Assert(m == null);

                    // /あ{2}/s matches "ああ\xff", current KCODE is ignored
                    m = rs.Match(RubyEncoding.KCodeUTF8, u, 2, false);
                    Assert(m != null && m.Index == 2 && m.Length == 4);


                    // /あ{2}/ does not match "あ\xa0あ\xa0"
                    m = r.LastMatch(RubyEncoding.KCodeSJIS, t);
                    Assert(m == null);

                    // /\x82\xa0{2}/ matches "\x82\xa0\xa0 [ \x82\xa0\xa0 ] \xff"
                    m = r.LastMatch(null, t);
                    Assert(m != null && m.Index == 3);

                    // /あ{2}/s does not match "あ\xa0あ\xa0", current KCODE is ignored
                    m = rs.LastMatch(null, t);
                    Assert(m == null);

                    // /あ{2}/s does not match "あ\xa0あ\xa0", current KCODE is ignored
                    m = rs.LastMatch(RubyEncoding.KCodeUTF8, t);
                    Assert(m == null);
                }
            }
        }
Beispiel #27
0
 public static MutableString Scan(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern)
 {
     return(ScanFull(self, pattern, true, true) as MutableString);
 }
Beispiel #28
0
 private bool Match(RubyRegex/*!*/ pattern, bool currentPositionOnly, bool advancePosition) {
     Match match = pattern.Match(_scanString, _currentPosition);
     _lastMatch = null;
     _lastMatchingGroups = null;
     _foundPosition = 0;
     if (!match.Success) {
         return false;
     }
     if (currentPositionOnly && match.Index != _currentPosition) {
         return false;
     }
     int length = (match.Index - _currentPosition) + match.Length;
     _foundPosition = match.Index;
     _previousPosition = _currentPosition;
     _lastMatch = _scanString.GetSlice(_foundPosition, match.Length);
     _lastMatchingGroups = match.Groups;
     if (advancePosition) {
         _currentPosition += length;
     }
     return true;
 }
Beispiel #29
0
        // returns true if block jumped
        // "result" will be null if there is no successful match
        private static bool BlockReplaceFirst(RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block,
            RubyRegex/*!*/ pattern, out object blockResult, out MutableString result) {

            var matchScope = scope.GetInnerMostClosureScope();
            MatchData match = RegexpOps.Match(scope, pattern, input);
            if (match == null || !match.Success) {
                result = null;
                blockResult = null;
                matchScope.CurrentMatch = null;
                return false;
            }

            // copy upfront so that no modifications to the input string are included in the result:
            result = input.Clone();
            matchScope.CurrentMatch = match;

            if (block.Yield(MutableString.Create(match.Value), out blockResult)) {
                return true;
            }

            // resets the $~ scope variable to the last match (skipd if block jumped):
            matchScope.CurrentMatch = match;

            MutableString replacement = Protocols.ConvertToString(scope.RubyContext, blockResult);
            result.TaintBy(replacement);

            // Note - we don't interpolate special sequences like \1 in block return value
            result.Replace(match.Index, match.Length, replacement);

            blockResult = null;
            return false;
        }
Beispiel #30
0
 public static object ImplicitMatch(ConversionStorage<MutableString>/*!*/ stringCast, RubyScope/*!*/ scope, RubyRegex/*!*/ self) {
     return MatchIndex(scope, self, Protocols.CastToString(stringCast, scope.GetInnerMostClosureScope().LastInputLine));
 }
Beispiel #31
0
 public static object ScanUntil(StringScanner /*!*/ self, [NotNull] RubyRegex /*!*/ pattern)
 {
     return(SearchFull(self, pattern, true, true));
 }
Beispiel #32
0
        public void RegexEncoding2()
        {
            var SJIS = RubyEncoding.KCodeSJIS.StrictEncoding;

            // 1.9 encodings:
            var invalidUtf8 = MutableString.CreateBinary(new byte[] { 0x80 }, RubyEncoding.UTF8);

            AssertExceptionThrown <ArgumentException>(() => new RubyRegex(invalidUtf8, RubyRegexOptions.NONE));

            // LastMatch

            MatchData m;
            var       u = MutableString.CreateBinary(SJIS.GetBytes("あああ"), RubyEncoding.KCodeSJIS);
            var       p = MutableString.CreateBinary(SJIS.GetBytes("あ{2}"), RubyEncoding.KCodeSJIS);

            var rs = new RubyRegex(p, RubyRegexOptions.SJIS);

            // /あ{2}/ matches "あああ", the resulting index is in bytes:
            m = rs.LastMatch(null, u);
            Assert(m != null && m.Index == 2);

            rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("あ")), RubyRegexOptions.SJIS);

            // "start at" in the middle of a character:
            m = rs.LastMatch(null, u, 0);
            Assert(m != null && m.Index == 0);

            m = rs.LastMatch(null, u, 1);
            Assert(m != null && m.Index == 0);

            m = rs.LastMatch(null, u, 2);
            Assert(m != null && m.Index == 2);

            m = rs.LastMatch(null, u, 3);
            Assert(m != null && m.Index == 2);

            // Split

            u  = MutableString.CreateBinary(SJIS.GetBytes("あちあちあ"), RubyEncoding.UTF8);
            rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("ち")), RubyRegexOptions.SJIS);
            var parts = rs.Split(null, u);

            Assert(parts.Length == 3);
            foreach (var part in parts)
            {
                Assert(part.Encoding == RubyEncoding.KCodeSJIS);
                Assert(part.ToString() == "あ");
            }

            // groups

            rs = new RubyRegex(MutableString.CreateBinary(SJIS.GetBytes("ち(a(あ+)(b+))+あ")), RubyRegexOptions.SJIS);
            u  = MutableString.CreateBinary(SJIS.GetBytes("ちaああbaあbbbあ"));

            m = rs.Match(null, u);
            Assert(m.GroupCount == 4);

            int s, l;

            Assert(m.GetGroupStart(0) == (s = 0));
            Assert(m.GetGroupLength(0) == (l = u.GetByteCount()));
            Assert(m.GetGroupEnd(0) == s + l);

            // the group has 2 captures, the last one is its value:
            Assert(m.GetGroupStart(1) == (s = SJIS.GetByteCount("ちaああb")));
            Assert(m.GetGroupLength(1) == (l = SJIS.GetByteCount("aあbbb")));
            Assert(m.GetGroupEnd(1) == s + l);

            // the group has 2 captures, the last one is its value:
            Assert(m.GetGroupStart(2) == (s = SJIS.GetByteCount("ちaああba")));
            Assert(m.GetGroupLength(2) == (l = SJIS.GetByteCount("あ")));
            Assert(m.GetGroupEnd(2) == s + l);

            // the group has 2 captures, the last one is its value:
            Assert(m.GetGroupStart(3) == (s = SJIS.GetByteCount("ちaああbaあ")));
            Assert(m.GetGroupLength(3) == (l = SJIS.GetByteCount("bbb")));
            Assert(m.GetGroupEnd(3) == s + l);
        }
Beispiel #33
0
 public static MutableString/*!*/ Source(RubyRegex/*!*/ self) {
     return self.GetPattern();
 }
Beispiel #34
0
 public static MutableString/*!*/ TagUri(RubyRegex/*!*/ self) {
     return MutableString.Create("tag:ruby.yaml.org,2002:regexp");
 }
Beispiel #35
0
 public static RubyRegex/*!*/ Reinitialize(RubyRegex/*!*/ self, [NotNull]RubyRegex/*!*/ other) {
     self.Set(other.GetPattern(), other.Options);
     return self;
 }
Beispiel #36
0
        // returns true if block jumped
        // "result" will be null if there is no successful match
        private static bool BlockReplaceAll(ConversionStorage<MutableString>/*!*/ tosConversion, 
            RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block,
            RubyRegex/*!*/ regex, out object blockResult, out MutableString result) {

            var matchScope = scope.GetInnerMostClosureScope();

            var matches = regex.Matches(tosConversion.Context.KCode, input);
            if (matches.Count == 0) {
                result = null;
                blockResult = null;
                matchScope.CurrentMatch = null;
                return false;
            }

            // create an empty result:
            result = input.CreateInstance().TaintBy(input);
            
            int offset = 0;
            foreach (MatchData match in matches) {
                matchScope.CurrentMatch = match;

                input.TrackChanges();
                if (block.Yield(match.GetValue(), out blockResult)) {
                    return true;
                }
                if (input.HasChanged) {
                    return false;
                }

                // resets the $~ scope variable to the last match (skipd if block jumped):
                matchScope.CurrentMatch = match;

                MutableString replacement = Protocols.ConvertToString(tosConversion, blockResult);
                result.TaintBy(replacement);

                // prematch:
                result.Append(input, offset, match.Index - offset);

                // replacement (unlike ReplaceAll, don't interpolate special sequences like \1 in block return value):
                result.Append(replacement);

                offset = match.Index + match.Length;
            }

            // post-last-match:
            result.Append(input, offset, input.Length - offset);

            blockResult = null;
            return false;
        }
Beispiel #37
0
        public static RubyRegex/*!*/ Reinitialize(RubyContext/*!*/ context, RubyRegex/*!*/ self,
            [NotNull]RubyRegex/*!*/ regex, int options, [Optional]object encoding) {

            ReportParametersIgnoredWarning(context, encoding);
            return Reinitialize(self, regex);
        }
Beispiel #38
0
 private static object MatchToScanResult(RubyScope/*!*/ scope, MutableString/*!*/ self, RubyRegex/*!*/ regex, MatchData/*!*/ match) {
     if (match.GroupCount == 1) {
         return match.GetValue().TaintBy(regex, scope);
     } else {
         var result = new RubyArray(match.GroupCount - 1);
         for (int i = 1; i < match.GroupCount; i++) {
             MutableString value = match.GetGroupValue(i);
             result.Add(value != null ? value.TaintBy(regex, scope) : value);
         }
         return result;
     }
 }
Beispiel #39
0
        public static RubyRegex/*!*/ Reinitialize(RubyContext/*!*/ context, RubyRegex/*!*/ self,
            [NotNull]RubyRegex/*!*/ regex, [DefaultParameterValue(null)]object ignoreCase, [Optional]object encoding) {

            ReportParametersIgnoredWarning(context, encoding);
            return Reinitialize(self, regex);
        }
Beispiel #40
0
 private bool Match(RubyRegex/*!*/ pattern, bool currentPositionOnly, bool advancePosition)
 {
     // TODO: repeated calls on the same ScanString can be optimized:
     MatchData match = pattern.Match(_scanString, _currentPosition, false);
     _lastMatch = null;
     _lastMatchingGroups = null;
     _foundPosition = 0;
     if (match == null) {
         return false;
     }
     if (currentPositionOnly && match.Index != _currentPosition) {
         return false;
     }
     int length = (match.Index - _currentPosition) + match.Length;
     _foundPosition = match.Index;
     _previousPosition = _currentPosition;
     _lastMatch = _scanString.GetSlice(_foundPosition, match.Length);
     _lastMatchingGroups = match;
     if (advancePosition) {
         _currentPosition += length;
     }
     return true;
 }
Beispiel #41
0
        public static RubyRegex/*!*/ Reinitialize(RubyRegex/*!*/ self, 
            [DefaultProtocol, NotNull]MutableString/*!*/ pattern, int options, [DefaultProtocol, Optional]MutableString encoding) {

            self.Set(pattern, MakeOptions(options, encoding));
            return self;
        }
Beispiel #42
0
        // returns true if block jumped
        // "result" will be null if there is no successful match
        private static bool BlockReplaceAll(RubyScope/*!*/ scope, MutableString/*!*/ input, BlockParam/*!*/ block,
            RubyRegex/*!*/ regex, out object blockResult, out MutableString result) {

            var matchScope = scope.GetInnerMostClosureScope();

            MatchCollection matches = regex.Matches(input);
            if (matches.Count == 0) {
                result = null;
                blockResult = null;
                matchScope.CurrentMatch = null;
                return false;
            }

            // create an empty result:
            result = input.CreateInstance().TaintBy(input);
            
            int offset = 0;
            foreach (Match match in matches) {
                MatchData currentMatch = new MatchData(match, input);
                matchScope.CurrentMatch = currentMatch;

                uint version = input.Version;
                if (block.Yield(MutableString.Create(match.Value), out blockResult)) {
                    return true;
                }
                if (input.Version != version) {
                    return false;
                }

                // resets the $~ scope variable to the last match (skipd if block jumped):
                matchScope.CurrentMatch = currentMatch;

                MutableString replacement = Protocols.ConvertToString(scope.RubyContext, blockResult);
                result.TaintBy(replacement);

                // prematch:
                result.Append(input, offset, match.Index - offset);

                // replacement (unlike ReplaceAll, don't interpolate special sequences like \1 in block return value):
                result.Append(replacement);

                offset = match.Index + match.Length;
            }

            // post-last-match:
            result.Append(input, offset, input.Length - offset);

            blockResult = null;
            return false;
        }
Beispiel #43
0
 private void WriteRegex(RubyRegex/*!*/ value) {
     SubclassData instanceWriter = new SubclassData(this, value, typeof(RubyRegex));
     _writer.Write((byte)'/');
     WriteStringValue(value.GetPattern());
     _writer.Write((byte)value.Options);
 }
Beispiel #44
0
        private static MutableString ReplaceAll(RubyScope/*!*/ scope, MutableString/*!*/ input, MutableString/*!*/ replacement, 
            RubyRegex/*!*/ regex) {
            var matchScope = scope.GetInnerMostClosureScope();
            
            // case of all
            MatchCollection matches = regex.Matches(input);
            if (matches.Count == 0) {
                matchScope.CurrentMatch = null;
                return null;
            }

            MutableString result = input.CreateInstance().TaintBy(input).TaintBy(replacement);

            int offset = 0;
            foreach (Match match in matches) {
                result.Append(input, offset, match.Index - offset);
                AppendReplacementExpression(input, match, result, replacement);
                offset = match.Index + match.Length;
            }

            result.Append(input, offset, input.Length - offset);

            matchScope.CurrentMatch = new MatchData(matches[matches.Count - 1], input);
            return result;
        }
Beispiel #45
0
 private static object MatchToScanResult(RubyScope/*!*/ scope, MutableString/*!*/ self, RubyRegex/*!*/ regex, Match/*!*/ match) {
     if (match.Groups.Count == 1) {
         return MutableString.Create(match.Value).TaintBy(self).TaintBy(regex, scope);
     } else {
         var result = new RubyArray(match.Groups.Count - 1);
         for (int i = 1; i < match.Groups.Count; i++) {
             if (match.Groups[i].Success) {
                 result.Add(MutableString.Create(match.Groups[i].Value).TaintBy(self).TaintBy(regex, scope));
             } else {
                 result.Add(null);
             }
         }
         return result;
     }
 }
Beispiel #46
0
        public static object BlockReplaceAll(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, 
            [NotNull]MutableString matchString) {

            object blockResult;
            MutableString result;
            var regex = new RubyRegex(Regex.Escape(matchString.ToString()), RubyRegexOptions.NONE);

            uint version = self.Version;
            object r = BlockReplaceAll(scope, self, block, regex, out blockResult, out result) ? blockResult : (result ?? self.Clone());
            RequireNoVersionChange(version, self);
            return r;
        }
Beispiel #47
0
 public static MutableString TagUri([NotNull] RubyRegex self)
 {
     return(MutableString.Create("tag:ruby.yaml.org,2002:regexp"));
 }
Beispiel #48
0
        private static MutableString ReplaceInPlace(RubyScope/*!*/ scope, MutableString/*!*/ self, RubyRegex/*!*/ pattern,
            MutableString/*!*/ replacement, bool replaceAll) {
            
            MutableString builder = replaceAll ?
                ReplaceAll(scope, self, replacement, pattern) :
                ReplaceFirst(scope, self, replacement, pattern);
            
            // unsuccessful match:
            if (builder == null) {
                return null;
            }

            self.Replace(0, self.Length, builder);
            return self.TaintBy(builder);
        }
Beispiel #49
0
 private void WriteRegex(RubyRegex/*!*/ value) {
     WriteSubclassData(value, typeof(RubyRegex));
     _writer.Write((byte)'/');
     WriteStringValue(value.Pattern);
     _writer.Write((byte)value.Options);
 }
Beispiel #50
0
        private static Group MatchRegexp(RubyScope/*!*/ scope, MutableString/*!*/ self, RubyRegex/*!*/ regex, int occurrance) {
            MatchData match = RegexpOps.Match(scope, regex, self); 
            if (match == null || !match.Success)
                return null;

            // Normalize index against # Groups in Match
            if (occurrance < 0) {
                occurrance += match.Groups.Count;
                // Cannot refer to zero using negative indices 
                if (occurrance == 0) {
                    return null;
                }
            }

            if (occurrance < 0 || occurrance > match.Groups.Count) {
                return null;
            }

            return match.Groups[occurrance].Success ? match.Groups[occurrance] : null;
        }
 public static MutableString /*!*/ TagUri(RubyContext /*!*/ context, RubyRegex /*!*/ self)
 {
     return(RubyYaml.GetTagUri(context, self, Tags.RubyRegexp, typeof(RubyRegex)));
 }