svn path=/branches/mono-1-1-9/mcs/; revision=50438
[mono.git] / mcs / class / System / System.Text.RegularExpressions / debug.cs
1 //\r
2 // assembly:    System\r
3 // namespace:   System.Text.RegularExpressions\r
4 // file:        debug.cs\r
5 //\r
6 // author:      Dan Lewis (dlewis@gmx.co.uk)\r
7 //              (c) 2002\r
8 \r
9 //\r
10 // Permission is hereby granted, free of charge, to any person obtaining\r
11 // a copy of this software and associated documentation files (the\r
12 // "Software"), to deal in the Software without restriction, including\r
13 // without limitation the rights to use, copy, modify, merge, publish,\r
14 // distribute, sublicense, and/or sell copies of the Software, and to\r
15 // permit persons to whom the Software is furnished to do so, subject to\r
16 // the following conditions:\r
17 // \r
18 // The above copyright notice and this permission notice shall be\r
19 // included in all copies or substantial portions of the Software.\r
20 // \r
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
22 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
23 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
24 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
25 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
26 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
27 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
28 //\r
29 \r
30 using System;\r
31 using System.Collections;\r
32 \r
33 namespace System.Text.RegularExpressions {\r
34 \r
35         class Disassembler {\r
36                 public static void DisassemblePattern (ushort[] image) {\r
37                         DisassembleBlock (image, 0, 0);\r
38                 }\r
39         \r
40                 public static void DisassembleBlock (ushort[] image, int pc, int depth) {\r
41                         OpCode op;\r
42                         OpFlags flags;\r
43 \r
44                         for (;;) {\r
45                                 if (pc >= image.Length)\r
46                                         return;\r
47                         \r
48                                 PatternCompiler.DecodeOp (image[pc], out op, out flags);\r
49                                 Console.Write (FormatAddress (pc) + ": ");              // address\r
50                                 Console.Write (new string (' ', depth * 2));            // indent\r
51                                 Console.Write (DisassembleOp (image, pc));              // instruction\r
52                                 Console.WriteLine ();\r
53 \r
54                                 int skip;\r
55                                 switch (op) {\r
56                                 case OpCode.False: case OpCode.True: case OpCode.Until:\r
57                                         skip = 1;\r
58                                         break;\r
59 \r
60                                 case OpCode.Character: case OpCode.Category: case OpCode.Position:\r
61                                 case OpCode.Open: case OpCode.Close: case OpCode.Reference:\r
62                                 case OpCode.Sub: case OpCode.Branch: case OpCode.Jump: case OpCode.In:\r
63                                         skip = 2;\r
64                                         break;\r
65 \r
66                                 case OpCode.Balance: case OpCode.IfDefined: case OpCode.Range:\r
67                                 case OpCode.Test: case OpCode.Anchor:\r
68                                         skip = 3;\r
69                                         break;\r
70 \r
71                                 case OpCode.Repeat: case OpCode.FastRepeat: case OpCode.Info:\r
72                                         skip = 4;\r
73                                         break;\r
74 \r
75                                 case OpCode.String: skip = image[pc + 1] + 2; break;\r
76                                 case OpCode.Set: skip = image[pc + 2] + 3; break;\r
77 \r
78                                 default:\r
79                                         skip = 1;\r
80                                         break;\r
81                                 }\r
82 \r
83                                 pc += skip;\r
84                         }\r
85                 }\r
86 \r
87                 public static string DisassembleOp (ushort[] image, int pc) {\r
88                         OpCode op;\r
89                         OpFlags flags;\r
90 \r
91                         PatternCompiler.DecodeOp (image[pc], out op, out flags);\r
92                         string str = op.ToString ();\r
93                         if (flags != 0)\r
94                                 str += "[" + flags.ToString ("f") + "]";\r
95 \r
96                         switch (op) {\r
97                         case OpCode.False: case OpCode.True: case OpCode.Until:\r
98                         default:\r
99                                 break;\r
100 \r
101                         case OpCode.Info:\r
102                                 str += " " + image[pc + 1];\r
103                                 str += " (" + image[pc + 2] + ", " + image[pc + 3] + ")";\r
104                                 break;\r
105                         \r
106                         case OpCode.Character:\r
107                                 str += " '" + FormatChar ((char)image[pc + 1]) + "'";\r
108                                 break;\r
109 \r
110                         case OpCode.Category:\r
111                                 str += " /" + (Category)image[pc + 1];\r
112                                 break;\r
113                         \r
114                         case OpCode.Range:\r
115                                 str += " '" + FormatChar ((char)image[pc + 1]) + "', ";\r
116                                 str += " '" + FormatChar ((char)image[pc + 2]) + "'";\r
117                                 break;\r
118 \r
119                         case OpCode.Set:\r
120                                 str += " " + FormatSet (image, pc + 1);\r
121                                 break;\r
122 \r
123                         case OpCode.String:\r
124                                 str += " '" + ReadString (image, pc + 1) + "'";\r
125                                 break;\r
126 \r
127                         case OpCode.Position:\r
128                                 str += " /" + (Position)image[pc + 1];\r
129                                 break;\r
130 \r
131                         case OpCode.Open: case OpCode.Close: case OpCode.Reference:\r
132                                 str += " " + image[pc + 1];\r
133                                 break;\r
134 \r
135                         case OpCode.Balance:\r
136                                 str += " " + image[pc + 1] + " " + image[pc + 2];\r
137                                 break;\r
138 \r
139                         case OpCode.IfDefined: case OpCode.Anchor:\r
140                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
141                                 str += " " + image[pc + 2];\r
142                                 break;\r
143                         \r
144                         case OpCode.Sub: case OpCode.Branch: case OpCode.Jump:\r
145                         case OpCode.In:\r
146                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
147                                 break;\r
148 \r
149                         case OpCode.Test:\r
150                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
151                                 str += ", :" + FormatAddress (pc + image[pc + 2]);\r
152                                 break;\r
153 \r
154                         case OpCode.Repeat: case OpCode.FastRepeat:\r
155                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
156                                 str += " (" + image[pc + 2] + ", ";\r
157                                 if (image[pc + 3] == 0xffff)\r
158                                         str += "Inf";\r
159                                 else\r
160                                         str += image[pc + 3];\r
161                                 str += ")";\r
162                                 break;\r
163 \r
164                         }\r
165 \r
166                         return str;\r
167                 }\r
168 \r
169                 // private static members\r
170         \r
171                 private static string ReadString (ushort[] image, int pc) {\r
172                         int len = image[pc];\r
173                         char[] chars = new char[len];\r
174 \r
175                         for (int i = 0; i < len; ++ i)\r
176                                 chars[i] = (char)image[pc + i + 1];\r
177 \r
178                         return new string (chars);\r
179                 }\r
180 \r
181                 private static string FormatAddress (int pc) {\r
182                         return pc.ToString ("x4");\r
183                 }\r
184 \r
185                 private static string FormatSet (ushort[] image, int pc) {\r
186                         int lo = image[pc ++];\r
187                         int hi = (image[pc ++] << 4) - 1;\r
188 \r
189                         string str = "[";\r
190 \r
191                         bool hot = false;\r
192                         char a = (char)0, b;\r
193                         for (int i = 0; i <= hi; ++ i) {\r
194                                 bool m = (image[pc + (i >> 4)] & (1 << (i & 0xf))) != 0;\r
195 \r
196                                 if (m & !hot) {                         // start of range\r
197                                         a = (char)(lo + i);\r
198                                         hot = true;\r
199                                 }\r
200                                 else if (hot & (!m || i == hi)) {       // end of range\r
201                                         b = (char)(lo + i - 1);\r
202 \r
203                                         str += FormatChar (a);\r
204                                         if (b != a)\r
205                                                 str += "-" + FormatChar (b);\r
206                                         \r
207                                         hot = false;\r
208                                 }\r
209                         }\r
210 \r
211                         str += "]";\r
212                         return str;\r
213                 }\r
214 \r
215                 private static string FormatChar (char c) {\r
216                         if (c == '-' || c == ']')\r
217                                 return "\\" + c;\r
218 \r
219                         if (Char.IsLetterOrDigit (c) || Char.IsSymbol (c))\r
220                                 return c.ToString ();\r
221                         \r
222                         if (Char.IsControl (c)) {\r
223                                 return "^" + (char)('@' + c);\r
224                         }\r
225 \r
226                         return "\\u" + ((int)c).ToString ("x4");\r
227                 }\r
228         }\r
229 }\r