예제 #1
0
 public static RubyArray GetGroup(ConversionStorage<int>/*!*/ fixnumCast, MatchData/*!*/ self, [NotNull]Range/*!*/ range) {
     int begin, count;
     if (!IListOps.NormalizeRange(fixnumCast, self.Groups.Count, range, out begin, out count)) {
         return null;
     }
     return GetGroup(fixnumCast.Context, self, begin, count);
 }
예제 #2
0
 public static RubyArray GetGroup(RubyContext/*!*/ context, MatchData/*!*/ self, [NotNull]Range/*!*/ range) {
     int begin, count;
     if (!IListOps.NormalizeRange(context, self.Groups.Count, range, out begin, out count)) {
         return null;
     }
     return GetGroup(context, self, begin, count);
 }
예제 #3
0
 private void InitializeFrom(StringScanner/*!*/ other) {
     _currentPosition = other._currentPosition;
     _foundPosition = other._foundPosition;
     _lastMatch = other._lastMatch;
     _lastMatchingGroups = other._lastMatchingGroups;
     _previousPosition = other._previousPosition;
     _scanString = other.ScanString;
 }
예제 #4
0
 public static RubyArray/*!*/ Offset(MatchData/*!*/ self, [DefaultProtocol]int groupIndex) {
     self.RequireExistingGroup(groupIndex);
     RubyArray result = new RubyArray(2);
     if (self.GroupSuccess(groupIndex)) {
         result.Add(self.GetGroupStart(groupIndex));
         result.Add(self.GetGroupEnd(groupIndex));
     } else {
         result.Add(null);
         result.Add(null);
     }
     return result;
 }
예제 #5
0
 public static RubyArray/*!*/ Offset(MatchData/*!*/ self, [DefaultProtocol]int groupIndex) {
     var group = self.GetExistingGroup(groupIndex);
     RubyArray result = new RubyArray(2);
     if (group.Success) {
         result.Add(group.Index);
         result.Add(group.Index + group.Length);
     } else {
         result.Add(null);
         result.Add(null);
     }
     return result;
 }
예제 #6
0
        public static RubyArray GetGroup(RubyContext/*!*/ context, MatchData/*!*/ self, [DefaultProtocol]int start, [DefaultProtocol]int length) {
            if (!IListOps.NormalizeRange(self.Groups.Count, ref start, ref length)) {
                return null;
            }

            RubyArray result = new RubyArray();
            for (int i = 0; i < length; i++) {
                result.Add(self.GetGroupValue(context, start + i));
            }

            return result;
        }
예제 #7
0
 public static MatchData/*!*/ InitializeCopy(MatchData/*!*/ self, [NotNull]MatchData/*!*/ other) {
     self.InitializeFrom(other);
     return self;
 }
예제 #8
0
 public static MutableString/*!*/ Inspect(RubyContext/*!*/ context, MatchData/*!*/ self) {
     return RubyUtils.ObjectToMutableString(context, self);
 }
예제 #9
0
        public static object Select(RubyContext/*!*/ context, [NotNull]BlockParam/*!*/ block, MatchData/*!*/ self) {
            RubyArray result = new RubyArray();
            for (int i = 0; i < self.Groups.Count; i++) {
                MutableString value = self.GetGroupValue(context, i);

                object blockResult;
                if (block.Yield(value, out blockResult)) {
                    return blockResult;
                }

                if (RubyOps.IsTrue(blockResult)) {
                    result.Add(value);
                }
            }
            return result;
        }
예제 #10
0
        public static bool CaseCompare(RubyScope /*!*/ scope, RubyRegex /*!*/ self, [NotNull] MutableString /*!*/ str)
        {
            MatchData match = Match(scope, self, str);

            return((match != null && match.Success) ? true : false);
        }
예제 #11
0
        private static RubyArray /*!*/ ReturnMatchingGroups(RubyContext /*!*/ context, MatchData /*!*/ self, int groupIndex)
        {
            Debug.Assert(groupIndex >= 0);

            if (self.Groups.Count < groupIndex)
            {
                return(new RubyArray());
            }

            RubyArray result = new RubyArray(self.Groups.Count - groupIndex);

            for (int i = groupIndex; i < self.Groups.Count; i++)
            {
                result.Add(self.GetGroupValue(context, i));
            }
            return(result);
        }
예제 #12
0
 protected MatchData(MatchData/*!*/ data)
     : this(data._match, data._originalString, data._kIndices) {
 }
예제 #13
0
 public static MutableString /*!*/ PostMatch(MatchData /*!*/ self)
 {
     return(self.GetPostMatch());
 }
예제 #14
0
        public MatchData Match(RubyEncoding kcode, MutableString /*!*/ input)
        {
            string str;

            return(MatchData.Create(Transform(ref kcode, input, 0, out str).Match(str), input, true, str, kcode, 0));
        }
예제 #15
0
        public static object End(MatchData /*!*/ self, [DefaultProtocol] int groupIndex)
        {
            var group = self.GetExistingGroup(groupIndex);

            return(group.Success ? ScriptingRuntimeHelpers.Int32ToObject(group.Index + group.Length) : null);
        }
예제 #16
0
 public static MutableString /*!*/ ToS(RubyContext /*!*/ context, MatchData /*!*/ self)
 {
     return(MutableString.Create(self.Value).TaintBy(self, context));
 }
예제 #17
0
        public static object Select(RubyContext /*!*/ context, [NotNull] BlockParam /*!*/ block, MatchData /*!*/ self)
        {
            RubyArray result = new RubyArray();

            for (int i = 0; i < self.Groups.Count; i++)
            {
                MutableString value = self.GetGroupValue(context, i);

                object blockResult;
                if (block.Yield(value, out blockResult))
                {
                    return(blockResult);
                }

                if (RubyOps.IsTrue(blockResult))
                {
                    result.Add(value);
                }
            }
            return(result);
        }
예제 #18
0
 public static RubyArray /*!*/ ToArray(RubyContext /*!*/ context, MatchData /*!*/ self)
 {
     return(ReturnMatchingGroups(context, self, 0));
 }
예제 #19
0
 public static object End(MatchData/*!*/ self, [DefaultProtocol]int groupIndex) {
     var group = self.GetExistingGroup(groupIndex);
     return group.Success ? ScriptingRuntimeHelpers.Int32ToObject(group.Index + group.Length) : null;
 }
예제 #20
0
 public static RubyArray /*!*/ Captures(MatchData /*!*/ self)
 {
     return(ReturnMatchingGroups(self, 1));
 }
예제 #21
0
 public static RubyArray /*!*/ ToArray(MatchData /*!*/ self)
 {
     return(ReturnMatchingGroups(self, 0));
 }
예제 #22
0
 protected MatchData(MatchData /*!*/ data)
     : this(data._match, data._originalString, data._kIndices)
 {
 }
예제 #23
0
 public static MutableString /*!*/ ReturnFrozenString(RubyContext /*!*/ context, MatchData /*!*/ self)
 {
     return(MutableString.Create(self.OriginalString).TaintBy(self, context).Freeze());
 }
예제 #24
0
 private static void AppendReplacementExpression(MutableString/*!*/ input, MatchData/*!*/ match, MutableString/*!*/ result, MutableString/*!*/ replacement) {
     AppendReplacementExpression(input, match.Groups, result, replacement);
 }
예제 #25
0
 public static MutableString /*!*/ Inspect(RubyContext /*!*/ context, MatchData /*!*/ self)
 {
     return(RubyUtils.ObjectToMutableString(context, self));
 }
예제 #26
0
 public static MutableString/*!*/ ReturnFrozenString(RubyContext/*!*/ context, MatchData/*!*/ self) {
     return MutableString.Create(self.OriginalString).TaintBy(self, context).Freeze();
 }
예제 #27
0
 public static MutableString /*!*/ ToS(MatchData /*!*/ self)
 {
     return(self.GetValue());
 }
예제 #28
0
        public static RubyArray/*!*/ ValuesAt(ConversionStorage<int>/*!*/ conversionStorage, 
            MatchData/*!*/ self, [DefaultProtocol, NotNull]params int[]/*!*/ indices) {

            RubyArray result = new RubyArray();
            for (int i = 0; i < indices.Length; i++) {
                result.Add(GetGroup(conversionStorage.Context, self, indices[i]));
            }
            return result;
        }
예제 #29
0
 public static MatchData /*!*/ InitializeCopy(MatchData /*!*/ self, [NotNull] MatchData /*!*/ other)
 {
     self.InitializeFrom(other);
     return(self);
 }
예제 #30
0
 public static MutableString/*!*/ ToS(RubyContext/*!*/ context, MatchData/*!*/ self) {
     return MutableString.Create(self.Value).TaintBy(self, context);
 }
예제 #31
0
 public static MutableString GetGroup(MatchData /*!*/ self, [DefaultProtocol] int index)
 {
     index = IListOps.NormalizeIndex(self.GroupCount, index);
     return(self.GetGroupValue(index));
 }
예제 #32
0
 public static MutableString GetGroup(RubyContext/*!*/ context, MatchData/*!*/ self, [DefaultProtocol]int index) {
     index = IListOps.NormalizeIndex(self.Groups.Count, index);
     return self.GetGroupValue(context, index);
 }
예제 #33
0
 public static object End(MatchData /*!*/ self, [DefaultProtocol] int groupIndex)
 {
     self.RequireExistingGroup(groupIndex);
     return(self.GroupSuccess(groupIndex) ? ScriptingRuntimeHelpers.Int32ToObject(self.GetGroupEnd(groupIndex)) : null);
 }
예제 #34
0
 public void InitializeFrom(MatchData /*!*/ other)
 {
     _match          = other._match;
     _kIndices       = other._kIndices;
     _originalString = other._originalString;
 }
예제 #35
0
 public static int Length(MatchData /*!*/ self)
 {
     return(self.GroupCount);
 }
예제 #36
0
 public static int Length(MatchData/*!*/ self) {
     return self.Groups.Count;
 }
예제 #37
0
        private static void AppendLastCharOfLastMatchGroup(MatchData/*!*/ match, MutableString/*!*/ result) {
            int i = match.GroupCount - 1;
            // move to last successful match group
            while (i > 0 && !match.GroupSuccess(i)) {
                i--;
            }

            if (i > 0 && match.GroupSuccess(i)) {
                int length = match.GetGroupLength(i);
                if (length > 0) {
                   result.Append(match.OriginalString, match.GetGroupStart(i) + length - 1, 1);
                }
            }
        }
예제 #38
0
 public static MutableString/*!*/ PreMatch(RubyContext/*!*/ context, MatchData/*!*/ self) {
     return self.OriginalString.GetSlice(0, self.Index).TaintBy(self, context);
 }
예제 #39
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;
     }
 }
예제 #40
0
 public void InitializeFrom(MatchData/*!*/ other) {
     _match = other._match;
     _kIndices = other._kIndices;
     _originalString = other._originalString;
 }
예제 #41
0
 private void Reset()
 {
     _previousPosition = 0;
     _currentPosition = 0;
     _foundPosition = 0;
     _lastMatch = null;
     _lastMatchingGroups = null;
 }
예제 #42
0
        private static void AppendReplacementExpression(MutableString/*!*/ input, MatchData/*!*/ match, MutableString/*!*/ result, 
            MutableString/*!*/ replacement) {

            int backslashCount = 0;
            for (int i = 0; i < replacement.Length; i++) {
                char c = replacement.GetChar(i);
                if (c == '\\') {
                    backslashCount++;
                } else if (backslashCount == 0) {
                    result.Append(c);
                } else {
                    AppendBackslashes(backslashCount, result, 0);
                    // Odd number of \'s + digit means insert replacement expression
                    if ((backslashCount & 1) == 1) {
                        if (Char.IsDigit(c)) {
                            AppendGroupByIndex(match, c - '0', result);
                        } else if (c == '&') {
                            AppendGroupByIndex(match, match.GroupCount - 1, result);
                        } else if (c == '`') {
                            // Replace with everything in the input string BEFORE the match
                            result.Append(input, 0, match.Index);
                        } else if (c == '\'') {
                            // Replace with everything in the input string AFTER the match
                            int start = match.Index + match.Length;
                            // TODO:
                            result.Append(input, start, input.GetLength() - start);
                        } else if (c == '+') {
                            // Replace last character in last successful match group
                            AppendLastCharOfLastMatchGroup(match, result);
                        } else {
                            // unknown escaped replacement char, go ahead and replace untouched
                            result.Append('\\');
                            result.Append(c);
                        }
                    } else {
                        // Any other # of \'s or a non-digit character means insert literal \'s and character
                        AppendBackslashes(backslashCount, result, 1);
                        result.Append(c);
                    }
                    backslashCount = 0;
                }
            }
            AppendBackslashes(backslashCount, result, 1);
        }
예제 #43
0
 public static MutableString /*!*/ PostMatch(RubyContext /*!*/ context, MatchData /*!*/ self)
 {
     return(self.OriginalString.GetSlice(self.Index + self.Length).TaintBy(self, context));
 }
예제 #44
0
 private static void AppendGroupByIndex(MatchData/*!*/ match, int index, MutableString/*!*/ result) {
     var value = match.GetGroupValue(index);
     if (value != null) {
         result.Append(value);
     }
 }
예제 #45
0
        private static RubyArray/*!*/ ReturnMatchingGroups(RubyContext/*!*/ context, MatchData/*!*/ self, int groupIndex) {
            Debug.Assert(groupIndex >= 0);
            
            if (self.Groups.Count < groupIndex) {
                return new RubyArray();
            }

            RubyArray result = new RubyArray(self.Groups.Count - groupIndex);
            for (int i = groupIndex; i < self.Groups.Count; i++) {
                result.Add(self.GetGroupValue(context, i));
            }
            return result;
        }
예제 #46
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;
 }
예제 #47
0
 public static RubyArray/*!*/ Captures(RubyContext/*!*/ context, MatchData/*!*/ self) {
     return ReturnMatchingGroups(context, self, 1);
 }
예제 #48
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;
        }
예제 #49
0
 public static RubyArray/*!*/ ToArray(RubyContext/*!*/ context, MatchData/*!*/ self) {
     return ReturnMatchingGroups(context, self, 0);
 }
예제 #50
0
        public static object/*!*/ Scan(RubyScope/*!*/ scope, [NotNull]BlockParam/*!*/ block, MutableString/*!*/ self, [DefaultProtocol, NotNull]RubyRegex regex) {
            var matchScope = scope.GetInnerMostClosureScope();
            
            MatchCollection matches = regex.Matches(self);
            if (matches.Count == 0) {
                matchScope.CurrentMatch = null;
                return self;
            } 

            foreach (Match match in matches) {
                var currentMatch = new MatchData(match, self);

                matchScope.CurrentMatch = currentMatch;

                object blockResult;
                if (block.Yield(MatchToScanResult(scope, self, regex, match), out blockResult)) {
                    return blockResult;
                }

                // resets the $~ scope variable to the last match (skipd if block jumped):
                matchScope.CurrentMatch = currentMatch;
            }
            return self;
        }
예제 #51
0
        public static object MatchIndex(RubyScope /*!*/ scope, RubyRegex /*!*/ self, [DefaultProtocol] MutableString /*!*/ str)
        {
            MatchData match = RubyRegex.SetCurrentMatchData(scope, self, str);

            return((match != null) ? ScriptingRuntimeHelpers.Int32ToObject(match.Index) : null);
        }