[System.Net] Add support for .pac proxy config scripts on mac
[mono.git] / mcs / class / System / System.Text.RegularExpressions / BackReferenceConstruct.jvm.cs
1 //
2 // BackReferenceConstruct.jvm.cs
3 //
4 // Author:
5 //      Arina Itkes  <arinai@mainsoft.com>
6 //
7 // Copyright (C) 2007 Mainsoft, Inc.
8 //
9
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30
31
32 using System;
33 using System.Collections.Generic;
34 using System.Text;
35 using java.util.regex;
36 using java.lang;
37
38 namespace System.Text.RegularExpressions
39 {
40         sealed class BackReferenceConstruct : IConstructType
41         {
42                 private const string NUMBER_BACK_REFERENCE_PATTERN = @"(?<=(?:[^\\]|\A)(?:[\\]{2}){0,1073741823})\\(\d+)";
43                 private const string NAME_1_BACK_REFERENCE_PATTERN = @"(?<=(?:[^\\]|\A)(?:[\\]{2}){0,1073741823})\\k<(\w+)>";
44                 private const string NAME_2_BACK_REFERENCE_PATTERN = @"(?<=(?:[^\\]|\A)(?:[\\]{2}){0,1073741823})\\k'(\w+)'";
45                 private const string NUMBER = @"\d+";
46
47
48                 public bool HasConstruct (string pattern, RegexOptions options) {
49                         if (JavaUtils.IsMatch (pattern, NUMBER_BACK_REFERENCE_PATTERN)) {
50                                 return true;
51                         }
52
53                         if (JavaUtils.IsMatch (pattern, NAME_1_BACK_REFERENCE_PATTERN)) {
54                                 return true;
55                         }
56
57                         return JavaUtils.IsMatch (pattern, NAME_2_BACK_REFERENCE_PATTERN);
58                 }
59
60                 public string Reformat (RegexOptions options,
61                         string reformattedPattern,
62                         PatternGrouping patternGrouping) {
63                         if (!HasConstruct (reformattedPattern, options)) {
64                                 return reformattedPattern;
65                         }
66
67                         if (patternGrouping.GroupCount >= 0 && patternGrouping.SameGroupsFlag) {
68                                 return null;
69                         }
70
71                         Matcher m = JavaUtils.Matcher (reformattedPattern, NUMBER_BACK_REFERENCE_PATTERN);
72                         if (m.find ()) {
73                                 reformattedPattern = ReplaceGroupNumber (m, reformattedPattern, patternGrouping, options);
74                                 if (reformattedPattern == null)
75                                         return null;
76                         }
77
78                         m = JavaUtils.Matcher(reformattedPattern, NAME_1_BACK_REFERENCE_PATTERN);
79                         if (m.find ()) {
80                                 reformattedPattern = ReplaceGroupName (m, reformattedPattern, patternGrouping, options);
81                                 if (reformattedPattern == null)
82                                         return null;
83                         }
84
85                         m = JavaUtils.Matcher(reformattedPattern, NAME_2_BACK_REFERENCE_PATTERN);
86                         if (m.find ()) {
87                                 reformattedPattern = ReplaceGroupName (m, reformattedPattern, patternGrouping, options);
88                                 if (reformattedPattern == null)
89                                         return null;
90                         }
91
92                         return reformattedPattern;
93                 }
94
95                 private string ReplaceGroupNumber (Matcher match,
96                         string reformattedPattern,
97                         PatternGrouping patternGrouping,
98                         RegexOptions options) {
99                         int groupNumber = int.Parse (match.group (1));
100                         int javaGroupNumber = groupNumber;
101                         int groupCount = patternGrouping.GroupCount;
102
103                         if (groupCount == -1) {
104                                 if ((options & RegexOptions.ExplicitCapture) == RegexOptions.ExplicitCapture) {
105                                         groupCount = 0;
106                                 }
107                                 else {
108                                         groupCount = JavaUtils.GroupCount (reformattedPattern);
109                                 }
110                         }
111                         else {
112                                 javaGroupNumber = patternGrouping.NetToJavaNumbersMap [groupNumber];
113                         }
114
115                         if (groupNumber > groupCount) {
116                                 return null;
117                         }
118
119                         return match.replaceFirst (@"\\" + javaGroupNumber);
120                 }
121
122                 private string ReplaceGroupName (Matcher match,
123                         string reformattedPattern,
124                         PatternGrouping patternGrouping,
125                         RegexOptions options) {
126
127                         if (patternGrouping.GroupCount == -1){
128                                 return null;
129                         }
130
131                         string groupName = match.group (1);
132                         Pattern p = Pattern.compile (NUMBER);
133                         Matcher m = p.matcher ((CharSequence) (object) groupName);
134                         if (m.matches ()) {
135                                 return ReplaceGroupNumber (match, reformattedPattern, patternGrouping, options);
136                         }
137
138                         if (!patternGrouping.GroupNameToNumberMap.Contains (groupName)) {
139                                 return null;
140                         }
141
142                         int javaGroupNumber = patternGrouping.NetToJavaNumbersMap [(int) patternGrouping.GroupNameToNumberMap [groupName]];
143                         return match.replaceFirst (@"\\" + javaGroupNumber);
144                 }
145         }
146 }