debug.cs 5.9 KB

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