2004-03-17 Francois Beauchemin <beauche@softhome.net>
[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 using System;\r
10 using System.Collections;\r
11 \r
12 namespace System.Text.RegularExpressions {\r
13 \r
14         class Disassembler {\r
15                 public static void DisassemblePattern (ushort[] image) {\r
16                         DisassembleBlock (image, 0, 0);\r
17                 }\r
18         \r
19                 public static void DisassembleBlock (ushort[] image, int pc, int depth) {\r
20                         OpCode op;\r
21                         OpFlags flags;\r
22 \r
23                         for (;;) {\r
24                                 if (pc >= image.Length)\r
25                                         return;\r
26                         \r
27                                 PatternCompiler.DecodeOp (image[pc], out op, out flags);\r
28                                 Console.Write (FormatAddress (pc) + ": ");              // address\r
29                                 Console.Write (new string (' ', depth * 2));            // indent\r
30                                 Console.Write (DisassembleOp (image, pc));              // instruction\r
31                                 Console.WriteLine ();\r
32 \r
33                                 int skip;\r
34                                 switch (op) {\r
35                                 case OpCode.False: case OpCode.True: case OpCode.Until:\r
36                                         skip = 1;\r
37                                         break;\r
38 \r
39                                 case OpCode.Character: case OpCode.Category: case OpCode.Position:\r
40                                 case OpCode.Open: case OpCode.Close: case OpCode.Reference:\r
41                                 case OpCode.Sub: case OpCode.Branch: case OpCode.Jump: case OpCode.In:\r
42                                         skip = 2;\r
43                                         break;\r
44 \r
45                                 case OpCode.Balance: case OpCode.IfDefined: case OpCode.Range:\r
46                                 case OpCode.Test: case OpCode.Anchor:\r
47                                         skip = 3;\r
48                                         break;\r
49 \r
50                                 case OpCode.Repeat: case OpCode.FastRepeat: case OpCode.Info:\r
51                                         skip = 4;\r
52                                         break;\r
53 \r
54                                 case OpCode.String: skip = image[pc + 1] + 2; break;\r
55                                 case OpCode.Set: skip = image[pc + 2] + 3; break;\r
56 \r
57                                 default:\r
58                                         skip = 1;\r
59                                         break;\r
60                                 }\r
61 \r
62                                 pc += skip;\r
63                         }\r
64                 }\r
65 \r
66                 public static string DisassembleOp (ushort[] image, int pc) {\r
67                         OpCode op;\r
68                         OpFlags flags;\r
69 \r
70                         PatternCompiler.DecodeOp (image[pc], out op, out flags);\r
71                         string str = op.ToString ();\r
72                         if (flags != 0)\r
73                                 str += "[" + flags.ToString ("f") + "]";\r
74 \r
75                         switch (op) {\r
76                         case OpCode.False: case OpCode.True: case OpCode.Until:\r
77                         default:\r
78                                 break;\r
79 \r
80                         case OpCode.Info:\r
81                                 str += " " + image[pc + 1];\r
82                                 str += " (" + image[pc + 2] + ", " + image[pc + 3] + ")";\r
83                                 break;\r
84                         \r
85                         case OpCode.Character:\r
86                                 str += " '" + FormatChar ((char)image[pc + 1]) + "'";\r
87                                 break;\r
88 \r
89                         case OpCode.Category:\r
90                                 str += " /" + (Category)image[pc + 1];\r
91                                 break;\r
92                         \r
93                         case OpCode.Range:\r
94                                 str += " '" + FormatChar ((char)image[pc + 1]) + "', ";\r
95                                 str += " '" + FormatChar ((char)image[pc + 2]) + "'";\r
96                                 break;\r
97 \r
98                         case OpCode.Set:\r
99                                 str += " " + FormatSet (image, pc + 1);\r
100                                 break;\r
101 \r
102                         case OpCode.String:\r
103                                 str += " '" + ReadString (image, pc + 1) + "'";\r
104                                 break;\r
105 \r
106                         case OpCode.Position:\r
107                                 str += " /" + (Position)image[pc + 1];\r
108                                 break;\r
109 \r
110                         case OpCode.Open: case OpCode.Close: case OpCode.Reference:\r
111                                 str += " " + image[pc + 1];\r
112                                 break;\r
113 \r
114                         case OpCode.Balance:\r
115                                 str += " " + image[pc + 1] + " " + image[pc + 2];\r
116                                 break;\r
117 \r
118                         case OpCode.IfDefined: case OpCode.Anchor:\r
119                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
120                                 str += " " + image[pc + 2];\r
121                                 break;\r
122                         \r
123                         case OpCode.Sub: case OpCode.Branch: case OpCode.Jump:\r
124                         case OpCode.In:\r
125                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
126                                 break;\r
127 \r
128                         case OpCode.Test:\r
129                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
130                                 str += ", :" + FormatAddress (pc + image[pc + 2]);\r
131                                 break;\r
132 \r
133                         case OpCode.Repeat: case OpCode.FastRepeat:\r
134                                 str += " :" + FormatAddress (pc + image[pc + 1]);\r
135                                 str += " (" + image[pc + 2] + ", ";\r
136                                 if (image[pc + 3] == 0xffff)\r
137                                         str += "Inf";\r
138                                 else\r
139                                         str += image[pc + 3];\r
140                                 str += ")";\r
141                                 break;\r
142 \r
143                         }\r
144 \r
145                         return str;\r
146                 }\r
147 \r
148                 // private static members\r
149         \r
150                 private static string ReadString (ushort[] image, int pc) {\r
151                         int len = image[pc];\r
152                         char[] chars = new char[len];\r
153 \r
154                         for (int i = 0; i < len; ++ i)\r
155                                 chars[i] = (char)image[pc + i + 1];\r
156 \r
157                         return new string (chars);\r
158                 }\r
159 \r
160                 private static string FormatAddress (int pc) {\r
161                         return pc.ToString ("x4");\r
162                 }\r
163 \r
164                 private static string FormatSet (ushort[] image, int pc) {\r
165                         int lo = image[pc ++];\r
166                         int hi = (image[pc ++] << 4) - 1;\r
167 \r
168                         string str = "[";\r
169 \r
170                         bool hot = false;\r
171                         char a = (char)0, b;\r
172                         for (int i = 0; i <= hi; ++ i) {\r
173                                 bool m = (image[pc + (i >> 4)] & (1 << (i & 0xf))) != 0;\r
174 \r
175                                 if (m & !hot) {                         // start of range\r
176                                         a = (char)(lo + i);\r
177                                         hot = true;\r
178                                 }\r
179                                 else if (hot & (!m || i == hi)) {       // end of range\r
180                                         b = (char)(lo + i - 1);\r
181 \r
182                                         str += FormatChar (a);\r
183                                         if (b != a)\r
184                                                 str += "-" + FormatChar (b);\r
185                                         \r
186                                         hot = false;\r
187                                 }\r
188                         }\r
189 \r
190                         str += "]";\r
191                         return str;\r
192                 }\r
193 \r
194                 private static string FormatChar (char c) {\r
195                         if (c == '-' || c == ']')\r
196                                 return "\\" + c;\r
197 \r
198                         if (Char.IsLetterOrDigit (c) || Char.IsSymbol (c))\r
199                                 return c.ToString ();\r
200                         \r
201                         if (Char.IsControl (c)) {\r
202                                 return "^" + (char)('@' + c);\r
203                         }\r
204 \r
205                         return "\\u" + ((int)c).ToString ("x4");\r
206                 }\r
207         }\r
208 }\r