* roottypes.cs: Rename from tree.cs.
[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.NotCategory:\r
61                                 case OpCode.Position:\r
62                                 case OpCode.Open: case OpCode.Close: case OpCode.Reference:\r
63                                 case OpCode.Sub: case OpCode.Branch: case OpCode.Jump: case OpCode.In:\r
64                                         skip = 2;\r
65                                         break;\r
66 \r
67                                 case OpCode.Balance: case OpCode.IfDefined: case OpCode.Range:\r
68                                 case OpCode.Test: case OpCode.Anchor:\r
69                                         skip = 3;\r
70                                         break;\r
71 \r
72                                 case OpCode.Repeat: case OpCode.FastRepeat: case OpCode.Info:\r
73                                         skip = 4;\r
74                                         break;\r
75 \r
76                                 case OpCode.String: skip = image[pc + 1] + 2; break;\r
77                                 case OpCode.Set: skip = image[pc + 2] + 3; break;\r
78 \r
79                                 default:\r
80                                         skip = 1;\r
81                                         break;\r
82                                 }\r
83 \r
84                                 pc += skip;\r
85                         }\r
86                 }\r
87 \r
88                 public static string DisassembleOp (ushort[] image, int pc) {\r
89                         OpCode op;\r
90                         OpFlags flags;\r
91 \r
92                         PatternCompiler.DecodeOp (image[pc], out op, out flags);\r
93                         string str = op.ToString ();\r
94                         if (flags != 0)\r
95                                 str += "[" + flags.ToString ("f") + "]";\r
96 \r
97                         switch (op) {\r
98                         case OpCode.False: case OpCode.True: case OpCode.Until:\r
99                         default:\r
100                                 break;\r
101 \r
102                         case OpCode.Info:\r
103                                 str += " " + image[pc + 1];\r
104                                 str += " (" + image[pc + 2] + ", " + image[pc + 3] + ")";\r
105                                 break;\r
106                         \r
107                         case OpCode.Character:\r
108                                 str += " '" + FormatChar ((char)image[pc + 1]) + "'";\r
109                                 break;\r
110 \r
111                         case OpCode.Category:\r
112                         case OpCode.NotCategory:\r
113                                 str += " /" + (Category)image[pc + 1];\r
114                                 break;\r
115                         \r
116                         case OpCode.Range:\r
117                                 str += " '" + FormatChar ((char)image[pc + 1]) + "', ";\r
118                                 str += " '" + FormatChar ((char)image[pc + 2]) + "'";\r
119                                 break;\r
120 \r
121                         case OpCode.Set:\r
122                                 str += " " + FormatSet (image, pc + 1);\r
123                                 break;\r
124 \r
125                         case OpCode.String:\r
126                                 str += " '" + ReadString (image, pc + 1) + "'";\r
127                                 break;\r
128 \r
129                         case OpCode.Position:\r
130                                 str += " /" + (Position)image[pc + 1];\r
131                                 break;\r
132 \r
133                         case OpCode.Open: case OpCode.Close: case OpCode.Reference:\r
134                                 str += " " + image[pc + 1];\r
135                                 break;\r
136 \r
137                         case OpCode.Balance:\r
138                                 str += " " + image[pc + 1] + " " + image[pc + 2];\r
139                                 break;\r
140 \r
141                         case OpCode.IfDefined: case OpCode.Anchor:\r
142                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
143                                 str += " " + image[pc + 2];\r
144                                 break;\r
145                         \r
146                         case OpCode.Sub: case OpCode.Branch: case OpCode.Jump:\r
147                         case OpCode.In:\r
148                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
149                                 break;\r
150 \r
151                         case OpCode.Test:\r
152                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
153                                 str += ", :" + FormatAddress (pc + image[pc + 2]);\r
154                                 break;\r
155 \r
156                         case OpCode.Repeat: case OpCode.FastRepeat:\r
157                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
158                                 str += " (" + image[pc + 2] + ", ";\r
159                                 if (image[pc + 3] == 0xffff)\r
160                                         str += "Inf";\r
161                                 else\r
162                                         str += image[pc + 3];\r
163                                 str += ")";\r
164                                 break;\r
165 \r
166                         }\r
167 \r
168                         return str;\r
169                 }\r
170 \r
171                 // private static members\r
172         \r
173                 private static string ReadString (ushort[] image, int pc) {\r
174                         int len = image[pc];\r
175                         char[] chars = new char[len];\r
176 \r
177                         for (int i = 0; i < len; ++ i)\r
178                                 chars[i] = (char)image[pc + i + 1];\r
179 \r
180                         return new string (chars);\r
181                 }\r
182 \r
183                 private static string FormatAddress (int pc) {\r
184                         return pc.ToString ("x4");\r
185                 }\r
186 \r
187                 private static string FormatSet (ushort[] image, int pc) {\r
188                         int lo = image[pc ++];\r
189                         int hi = (image[pc ++] << 4) - 1;\r
190 \r
191                         string str = "[";\r
192 \r
193                         bool hot = false;\r
194                         char a = (char)0, b;\r
195                         for (int i = 0; i <= hi; ++ i) {\r
196                                 bool m = (image[pc + (i >> 4)] & (1 << (i & 0xf))) != 0;\r
197 \r
198                                 if (m & !hot) {                         // start of range\r
199                                         a = (char)(lo + i);\r
200                                         hot = true;\r
201                                 }\r
202                                 else if (hot & (!m || i == hi)) {       // end of range\r
203                                         b = (char)(lo + i - 1);\r
204 \r
205                                         str += FormatChar (a);\r
206                                         if (b != a)\r
207                                                 str += "-" + FormatChar (b);\r
208                                         \r
209                                         hot = false;\r
210                                 }\r
211                         }\r
212 \r
213                         str += "]";\r
214                         return str;\r
215                 }\r
216 \r
217                 private static string FormatChar (char c) {\r
218                         if (c == '-' || c == ']')\r
219                                 return "\\" + c;\r
220 \r
221                         if (Char.IsLetterOrDigit (c) || Char.IsSymbol (c))\r
222                                 return c.ToString ();\r
223                         \r
224                         if (Char.IsControl (c)) {\r
225                                 return "^" + (char)('@' + c);\r
226                         }\r
227 \r
228                         return "\\u" + ((int)c).ToString ("x4");\r
229                 }\r
230         }\r
231 }\r