Trace.Mod 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. MODULE Trace; (** AUTHOR "fn"; PURPOSE "Low-level trace output based on KernelLog"; *)
  2. IMPORT SYSTEM;
  3. TYPE
  4. CharProc*= PROCEDURE (c:CHAR);
  5. VAR
  6. Char*: CharProc;
  7. Color*: PROCEDURE (c: SHORTINT);
  8. PROCEDURE Enter*;
  9. BEGIN {UNCOOPERATIVE, UNCHECKED}
  10. END Enter;
  11. PROCEDURE Exit*;
  12. BEGIN {UNCOOPERATIVE, UNCHECKED} Ln;
  13. END Exit;
  14. (** Send the specified characters to the trace output (cf. Streams.Sender). *)
  15. PROCEDURE Send*(CONST buf: ARRAY OF CHAR; ofs, len: LONGINT; propagate: BOOLEAN; VAR res: LONGINT);
  16. BEGIN {UNCOOPERATIVE, UNCHECKED} INC (len, ofs); ASSERT (len <= LEN (buf)); WHILE ofs # len DO Char (buf[ofs]); INC (ofs); END; res := 0;
  17. END Send;
  18. (** Skip to the next line on trace output. *)
  19. PROCEDURE Ln*;
  20. BEGIN {UNCOOPERATIVE, UNCHECKED} Char (0DX); Char (0AX);
  21. END Ln;
  22. (** Write a string to the trace output. *)
  23. PROCEDURE String* (CONST s: ARRAY OF CHAR);
  24. VAR i: SIZE; c: CHAR;
  25. BEGIN {UNCOOPERATIVE, UNCHECKED} FOR i := 0 TO LEN (s) - 1 DO c := s[i]; IF c = 0X THEN RETURN END; Char (c) END;
  26. END String;
  27. (** Write a string to the trace output and skip to next line. *)
  28. PROCEDURE StringLn* (CONST s: ARRAY OF CHAR);
  29. BEGIN {UNCOOPERATIVE, UNCHECKED} String (s); Ln;
  30. END StringLn;
  31. (** Write a character. *)
  32. PROCEDURE Int* (x: HUGEINT; w: SIZE);
  33. VAR i: SIZE; x0: HUGEINT; a: ARRAY 21 OF CHAR;
  34. BEGIN {UNCOOPERATIVE, UNCHECKED}
  35. IF x < 0 THEN
  36. IF x = MIN (HUGEINT) THEN
  37. DEC (w, 20);
  38. WHILE w > 0 DO Char (' '); DEC (w) END;
  39. String ("-9223372036854775808");
  40. RETURN
  41. ELSE
  42. DEC (w); x0 := -x
  43. END
  44. ELSE
  45. x0 := x
  46. END;
  47. i := 0;
  48. REPEAT
  49. a[i] := CHR (x0 MOD 10 + 30H); x0 := x0 DIV 10; INC (i)
  50. UNTIL x0 = 0;
  51. WHILE w > i DO Char (' '); DEC (w) END;
  52. IF x < 0 THEN Char ('-') END;
  53. REPEAT DEC (i); Char (a[i]) UNTIL i = 0
  54. END Int;
  55. PROCEDURE Boolean* (x : BOOLEAN);
  56. BEGIN {UNCOOPERATIVE, UNCHECKED} IF x THEN String ("TRUE") ELSE String ("FALSE") END
  57. END Boolean;
  58. (** Write "x" as a decimal number with a power-of-two multiplier (K, M or G), followed by "suffix". "w" is the field width, excluding "suffix". *)
  59. PROCEDURE IntSuffix* (x: HUGEINT; w: SIZE; CONST suffix: ARRAY OF CHAR);
  60. CONST K = 1024; M = K*K; G = K*M;
  61. VAR mult: CHAR;
  62. BEGIN {UNCOOPERATIVE, UNCHECKED}
  63. IF x MOD K # 0 THEN
  64. Int (x, w)
  65. ELSE
  66. IF x MOD M # 0 THEN mult := 'K'; x := x DIV K
  67. ELSIF x MOD G # 0 THEN mult := 'M'; x := x DIV M
  68. ELSE mult := 'G'; x := x DIV G
  69. END;
  70. Int (x, w-1); Char (mult)
  71. END;
  72. String (suffix)
  73. END IntSuffix;
  74. (**
  75. Write an integer in hexadecimal right-justified in a field of at least ABS(w) characters.
  76. If w < 0 THEN w least significant hex digits of x are written (possibly including leading zeros)
  77. *)
  78. PROCEDURE Hex*(x: HUGEINT; w: SIZE );
  79. VAR i: SIZE;
  80. buf: ARRAY 2*SIZEOF(HUGEINT)+2 OF CHAR;
  81. neg: BOOLEAN;
  82. c: HUGEINT;
  83. BEGIN {UNCOOPERATIVE, UNCHECKED}
  84. IF w >= 0 THEN
  85. i:= 0;
  86. IF x < 0 THEN neg := TRUE; x :=-x ELSIF x=0 THEN buf := "0" ELSE neg := FALSE END;
  87. i := 0;
  88. REPEAT
  89. c := x MOD 10H;
  90. IF c < 10 THEN buf[i] := CHR(c+ORD("0")) ELSE buf[i] := CHR(c-10+ORD("A")) END;
  91. x := x DIV 10H;
  92. INC(i);
  93. UNTIL (i = 2 * SIZEOF(HUGEINT)) OR (x=0);
  94. IF c > 9 THEN buf[i] := "0"; INC(i) END;
  95. IF neg THEN buf[i] := "-"; INC(i) END;
  96. WHILE(w > i) DO Char(" "); DEC(w); END;
  97. REPEAT DEC(i); Char(buf[i]); UNTIL i=0;
  98. ELSE
  99. w := -w;
  100. WHILE(w>2*SIZEOF(HUGEINT)) DO
  101. Char(" "); DEC(w);
  102. END;
  103. buf[w] := 0X;
  104. REPEAT
  105. DEC(w);
  106. c := x MOD 10H;
  107. IF c <10 THEN buf[w] := CHR(c+ORD("0")) ELSE buf[w] := CHR(c-10+ORD("A")) END;
  108. x := x DIV 10H;
  109. UNTIL w = 0;
  110. String(buf);
  111. END;
  112. END Hex;
  113. (** Write "x" as a hexadecimal address *)
  114. PROCEDURE Address* (x: ADDRESS);
  115. BEGIN {UNCOOPERATIVE, UNCHECKED}
  116. Hex(x,-2*SIZEOF(ADDRESS));
  117. END Address;
  118. (** Write "x" as a hexadecimal number. "w" is the field width. Always prints 16 digits. *)
  119. PROCEDURE HIntHex* (x: HUGEINT; w: SIZE);
  120. BEGIN {UNCOOPERATIVE, UNCHECKED} Hex (x, w);
  121. END HIntHex;
  122. (** Write a block of memory in hex. *)
  123. PROCEDURE Memory* (adr: ADDRESS; size: SIZE);
  124. VAR i, j: ADDRESS; ch: CHAR;
  125. BEGIN {UNCOOPERATIVE, UNCHECKED}
  126. size := adr+size-1;
  127. FOR i := adr TO size BY 16 DO
  128. Address (i); Char (' ');
  129. FOR j := i TO i+15 DO
  130. IF j <= size THEN
  131. SYSTEM.GET (j, ch);
  132. Char(' ');
  133. Hex (ORD (ch), -2)
  134. ELSE
  135. Char (' ');
  136. Char (' ');
  137. Char (' ');
  138. END
  139. END;
  140. Char (' '); Char (' ');
  141. FOR j := i TO i+15 DO
  142. IF j <= size THEN
  143. SYSTEM.GET (j, ch);
  144. IF (ch < ' ') OR (ch >= CHR (127)) THEN ch := '.' END;
  145. Char (ch)
  146. END
  147. END;
  148. Ln
  149. END;
  150. END Memory;
  151. (* Write basic stack frame information *)
  152. PROCEDURE StackFrames- (skip, count, size: SIZE);
  153. VAR frame {UNTRACED}: POINTER {UNSAFE} TO RECORD descriptor, previous, caller, parameters: ADDRESS END;
  154. BEGIN {UNCOOPERATIVE, UNCHECKED}
  155. frame := ADDRESS OF frame + SIZE OF ADDRESS;
  156. WHILE skip # 0 DO
  157. frame := frame.previous;
  158. IF frame = NIL THEN RETURN END;
  159. DEC (skip);
  160. END;
  161. WHILE count # 0 DO
  162. Address (frame.caller); Char (':'); Ln;
  163. IF frame.previous = NIL THEN RETURN END;
  164. IF frame.previous - ADDRESS OF frame.descriptor <= size THEN
  165. Memory (ADDRESS OF frame.parameters, frame.previous - ADDRESS OF frame.descriptor);
  166. ELSIF size # 0 THEN
  167. Memory (ADDRESS OF frame.parameters, size); String ("..."); Ln;
  168. END;
  169. DEC (count); frame := frame.previous;
  170. END;
  171. WHILE frame.previous # NIL DO INC (count); frame := frame.previous END;
  172. IF count # 0 THEN Char ('+'); Int (count, 0); Ln; END;
  173. END StackFrames;
  174. (** Write a buffer in hex. *)
  175. PROCEDURE Buffer* (CONST buf: ARRAY OF CHAR; ofs, len: LONGINT);
  176. BEGIN {UNCOOPERATIVE, UNCHECKED} Memory (ADDRESSOF (buf[ofs]), len)
  177. END Buffer;
  178. (** Write bits (ofs..ofs+n-1) of x in binary. *)
  179. PROCEDURE Bits* (x: SET; ofs, n: SIZE);
  180. BEGIN {UNCOOPERATIVE, UNCHECKED}
  181. REPEAT
  182. DEC (n);
  183. IF (ofs+n) IN x THEN Char ('1') ELSE Char ('0') END
  184. UNTIL n = 0
  185. END Bits;
  186. PROCEDURE Set*(x: SET);
  187. VAR first: BOOLEAN; i: SIZE;
  188. BEGIN
  189. first := TRUE;
  190. Char("{");
  191. FOR i := 0 TO MAX(SET) DO
  192. IF i IN x THEN
  193. IF ~first THEN Char(",") ELSE first := FALSE END;
  194. Int(i,1);
  195. END;
  196. END;
  197. Char("}");
  198. END Set;
  199. (** Colors *)
  200. PROCEDURE Blue*;
  201. BEGIN {UNCOOPERATIVE, UNCHECKED} Color (9);
  202. END Blue;
  203. PROCEDURE Green*;
  204. BEGIN {UNCOOPERATIVE, UNCHECKED} Color (10);
  205. END Green;
  206. PROCEDURE Red*;
  207. BEGIN {UNCOOPERATIVE, UNCHECKED} Color (12);
  208. END Red;
  209. PROCEDURE Yellow*;
  210. BEGIN {UNCOOPERATIVE, UNCHECKED} Color (14);
  211. END Yellow;
  212. PROCEDURE Default*;
  213. BEGIN {UNCOOPERATIVE, UNCHECKED} Color (7);
  214. END Default;
  215. PROCEDURE NullChar(c: CHAR);
  216. BEGIN {UNCOOPERATIVE, UNCHECKED}
  217. END NullChar;
  218. PROCEDURE NullColor(c: SHORTINT);
  219. BEGIN {UNCOOPERATIVE, UNCHECKED}
  220. END NullColor;
  221. PROCEDURE Init*;
  222. BEGIN {UNCOOPERATIVE, UNCHECKED}
  223. Char := NullChar;
  224. Color := NullColor;
  225. END Init;
  226. (*
  227. BEGIN
  228. Char := NullChar;
  229. Color := NullColor;
  230. *)
  231. END Trace.