123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321 |
- MODULE Trace; (** AUTHOR "fn"; PURPOSE "Low-level trace output based on KernelLog"; *)
- IMPORT SYSTEM;
- CONST MAXBUFLEN = 32;
- TYPE
- CharProc*= PROCEDURE (c:CHAR);
- VAR
- Char*: CharProc;
- Color*: PROCEDURE (c: SHORTINT);
- (** Send the specified characters to the trace output (cf. Streams.Sender). *)
- PROCEDURE Send*(CONST buf: ARRAY OF CHAR; ofs, len: LONGINT; propagate: BOOLEAN; VAR res: LONGINT);
- BEGIN INC (len, ofs); WHILE ofs # len DO Char (buf[ofs]); INC (ofs); END; res := 0;
- END Send;
- (** Skip to the next line on trace output. *)
- PROCEDURE Ln*;
- BEGIN Char (0DX); Char (0AX);
- END Ln;
- (** Write a string to the trace output. *)
- PROCEDURE String* (CONST s: ARRAY OF CHAR);
- VAR i: LONGINT;
- BEGIN i := 0; WHILE (i< LEN(s)) & (s[i] # 0X) DO Char (s[i]); INC (i) END;
- END String;
- PROCEDURE C*( CONST c : CHAR );
- BEGIN
- Char( c );
- END C;
- PROCEDURE StringA*( CONST s: ARRAY OF CHAR; CONST len : LONGINT; CONST addColon : BOOLEAN );
- VAR
- i : LONGINT;
- rest : LONGINT;
- BEGIN
- IF ( LEN( s ) < len ) THEN
- rest := len - LEN( s );
- ELSE
- rest := 0;
- END;
- String( s );
- FOR i := 0 TO rest -1 DO
- Char(' ');
- END;
- IF ( addColon ) THEN
- Char(':'); Char(' ');
- END;
- END StringA;
- PROCEDURE Real*(x: LONGREAL; dec, len: LONGINT);
- VAR
- res, i, n, x0: LONGINT;
- a: ARRAY MAXBUFLEN OF CHAR;
- z: LONGREAL;
- BEGIN
- n := 0;
- z := 1.0;
- WHILE n < dec DO
- z := z*10.0;
- INC(n)
- END;
- x0 := FLOOR(x*z);
- IF x < 0.0 THEN x0 := -x0 END;
- i := 0;
- IF n > 0 THEN
- WHILE i < n DO
- a[i] := CHR(x0 MOD 10 + 48);
- x0 := x0 DIV 10;
- INC(i)
- END;
- a[i] := '.';
- INC(i)
- END;
- REPEAT
- a[i] := CHR(x0 MOD 10 + 48);
- x0 := x0 DIV 10;
- INC(i)
- UNTIL (x0 = 0) OR (i = MAXBUFLEN);
- IF (x < 0.0) & (i < MAXBUFLEN) THEN a[i] := '-'; INC(i) END;
- WHILE (i < len) & (i < MAXBUFLEN) DO a[i] := ' '; INC(i) END;
- REPEAT DEC(i); Char( a[i] ); UNTIL i = 0
- END Real;
- (** Write a string to the trace output and skip to next line. *)
- PROCEDURE StringLn* (CONST s: ARRAY OF CHAR);
- BEGIN String (s); Ln;
- END StringLn;
- (** Write a character. *)
- PROCEDURE Int* (x,w: LONGINT);
- VAR i: SIZE; x0: LONGINT; a: ARRAY 21 OF CHAR;
- BEGIN
- IF x < 0 THEN
- IF x = MIN (LONGINT) THEN
- DEC (w, 20);
- WHILE w > 0 DO Char (' '); DEC (w) END;
- String ("-9223372036854775808");
- RETURN
- ELSE
- DEC (w); x0 := -x
- END
- ELSE
- x0 := x
- END;
- i := 0;
- REPEAT
- a[i] := CHR (x0 MOD 10 + 30H); x0 := x0 DIV 10; INC (i)
- UNTIL x0 = 0;
- WHILE w > i DO Char (' '); DEC (w) END;
- IF x < 0 THEN Char ('-') END;
- REPEAT DEC (i); Char (a[i]) UNTIL i = 0
- END Int;
- PROCEDURE HInt*( x : HUGEINT; w: LONGINT );
- VAR i: SIZE; x0: HUGEINT; a: ARRAY 32 OF CHAR;
- BEGIN
- IF x < 0 THEN
- IF x = MIN (HUGEINT) THEN
- DEC (w, 20);
- WHILE w > 0 DO Char (' '); DEC (w) END;
- String ("-tm");
- RETURN
- ELSE
- DEC (w); x0 := -x
- END
- ELSE
- x0 := x
- END;
- i := 0;
- REPEAT
- a[i] := CHR (x0 MOD 10 + 30H); x0 := x0 DIV 10; INC (i)
- UNTIL x0 = 0;
- WHILE w > i DO Char (' '); DEC (w) END;
- IF x < 0 THEN Char ('-') END;
- REPEAT DEC (i); Char (a[i]) UNTIL i = 0
- END HInt;
- PROCEDURE Boolean* (x : BOOLEAN);
- BEGIN IF x THEN String ("TRUE") ELSE String ("FALSE") END
- END Boolean;
- (** 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". *)
- PROCEDURE IntSuffix* (x, w: LONGINT; CONST suffix: ARRAY OF CHAR);
- CONST K = 1024; M = K*K; G = K*M;
- VAR mult: CHAR;
- BEGIN
- IF x MOD K # 0 THEN
- Int (x, w)
- ELSE
- IF x MOD M # 0 THEN mult := 'K'; x := x DIV K
- ELSIF x MOD G # 0 THEN mult := 'M'; x := x DIV M
- ELSE mult := 'G'; x := x DIV G
- END;
- Int (x, w-1); Char (mult)
- END;
- String (suffix)
- END IntSuffix;
- (**
- Write an integer in hexadecimal right-justified in a field of at least ABS(w) characters.
- If w < 0 THEN w least significant hex digits of x are written (possibly including leading zeros)
- *)
- PROCEDURE Hex*(x: LONGINT; w: LONGINT );
- VAR i: LONGINT;
- buf: ARRAY 2*SIZEOF(LONGINT)+2 OF CHAR;
- neg: BOOLEAN;
- c: LONGINT;
- BEGIN
- IF w >= 0 THEN
- i:= 0;
- IF x < 0 THEN neg := TRUE; x :=-x ELSIF x=0 THEN buf := "0" ELSE neg := FALSE END;
- i := 0;
- REPEAT
- c := x MOD 10H;
- IF c < 10 THEN buf[i] := CHR(c+ORD("0")) ELSE buf[i] := CHR(c-10+ORD("A")) END;
- x := x DIV 10H;
- INC(i);
- UNTIL (i = 2 * SIZEOF(LONGINT)) OR (x=0);
- IF c > 9 THEN buf[i] := "0"; INC(i) END;
- IF neg THEN buf[i] := "-"; INC(i) END;
- WHILE(w > i) DO Char(" "); DEC(w); END;
- REPEAT DEC(i); Char(buf[i]); UNTIL i=0;
- ELSE
- w := -w;
- WHILE(w>2*SIZEOF(LONGINT)) DO
- Char(" "); DEC(w);
- END;
- buf[w] := 0X;
- REPEAT
- DEC(w);
- c := x MOD 10H;
- IF c <10 THEN buf[w] := CHR(c+ORD("0")) ELSE buf[w] := CHR(c-10+ORD("A")) END;
- x := x DIV 10H;
- UNTIL w = 0;
- String(buf);
- END;
- END Hex;
- (** Write "x" as a hexadecimal address *)
- PROCEDURE Address* (x: ADDRESS);
- BEGIN
- Hex(x,-2*SIZEOF(ADDRESS));
- END Address;
- (** Write "x" as a hexadecimal number. "w" is the field width. Always prints 16 digits. *)
- PROCEDURE HIntHex* (x: LONGINT; w: LONGINT);
- BEGIN Hex (x, w);
- END HIntHex;
- (** Write "x" as a set. *)
- PROCEDURE Set*(x: SET);
- VAR first: BOOLEAN; i: LONGINT;
- BEGIN
- first := TRUE;
- Char("{");
- FOR i := 0 TO MAX(SET) DO
- IF i IN x THEN
- IF ~first THEN Char(",") ELSE first := FALSE END;
- Int(i,1);
- END;
- END;
- Char("}");
- END Set;
- (** Write a block of memory in hex. *)
- PROCEDURE Memory* (adr: ADDRESS; size: SIZE);
- VAR i, j: ADDRESS; ch: CHAR;
- BEGIN
- size := adr+size-1;
- FOR i := adr TO size BY 16 DO
- Address (i); Char (' ');
- FOR j := i TO i+15 DO
- IF j <= size THEN
- SYSTEM.GET (j, ch);
- Char(' ');
- Hex (ORD (ch), -2)
- ELSE
- Char (' ');
- END
- END;
- Char (' ');
- FOR j := i TO i+15 DO
- IF j <= size THEN
- SYSTEM.GET (j, ch);
- IF (ch < ' ') OR (ch >= CHR (127)) THEN ch := '.' END;
- Char (ch)
- END
- END;
- Ln
- END;
- END Memory;
- (** Write a buffer in hex. *)
- PROCEDURE Buffer* (CONST buf: ARRAY OF CHAR; ofs, len: LONGINT);
- BEGIN Memory (ADDRESSOF (buf[ofs]), len)
- END Buffer;
- (** Write bits (ofs..ofs+n-1) of x in binary. *)
- PROCEDURE Bits* (x: SET; ofs, n: LONGINT);
- BEGIN
- REPEAT
- DEC (n);
- IF (ofs+n) IN x THEN Char ('1') ELSE Char ('0') END
- UNTIL n = 0
- END Bits;
- (** Colors *)
- PROCEDURE Blue*;
- BEGIN Color (9);
- END Blue;
- PROCEDURE Green*;
- BEGIN Color (10);
- END Green;
- PROCEDURE Red*;
- BEGIN Color (12);
- END Red;
- PROCEDURE Yellow*;
- BEGIN Color (14);
- END Yellow;
- PROCEDURE Default*;
- BEGIN Color (7);
- END Default;
- PROCEDURE NullChar(c: CHAR);
- BEGIN
- END NullChar;
- PROCEDURE NullColor(c: SHORTINT);
- BEGIN
- END NullColor;
- PROCEDURE Init*;
- BEGIN
- Char := NullChar;
- Color := NullColor;
- END Init;
- PROCEDURE Enter *;
- END Enter;
- PROCEDURE Exit *;
- BEGIN
- Ln
- END Exit;
- (*
- BEGIN
- Char := NullChar;
- Color := NullColor;
- *)
- END Trace.
|