home *** CD-ROM | disk | FTP | other *** search
Modula Implementation | 1988-01-27 | 11.0 KB | 368 lines |
- IMPLEMENTATION MODULE Debugger;
- (*-------------------------------------------------------*
- * Das Modul Debugger enthält Routinen zur Fehlersuche. *
- * Die implementierten Funktionen schreiben bei ihrem *
- * Aufruf Informationen in eine Debugger-Datei vom Typ *
- * Stream. *
- * (C) 1988 Frank F. Wachtmeister & PASCAL International *
- *-------------------------------------------------------*)
-
- FROM SYSTEM IMPORT BYTE, WORD, LONGWORD, ADDRESS;
- FROM Streams IMPORT Stream, StreamKinds, OpenStream,
- CloseStream, EOS;
- FROM GEMX IMPORT ErrorCause, ErrorContextType,
- ErrorProcessor, ErrorContext,
- ErrorProcessorType;
- FROM TextIO IMPORT in, out, REad, REadString,
- WRiteString, WRiteCard, WRiteInt,
- WRiteReal, WRiteLn, WRiteOct, WRiteHex,
- WRiteAdr, WRiteHexAdr, WRite;
- FROM Strings IMPORT String, Length, Assign;
-
- (*-------------------------------------------------------*
- * Man kann auch eine spezielle Einlese-Prozedur verwen- *
- * den, aus der dann Zeile und Spalte verwendet werden *
- * können, um den Fehler in der Quelldatei zu lokali- *
- * sieren. Hier heißt sie Analyser. *
- *-------------------------------------------------------*
- * FROM Analyser IMPORT line, column; *
- *-------------------------------------------------------*)
-
- VAR
- init, active : BOOLEAN;
- i, SNr : CARDINAL;
- debugname : String;
- NormalError : ErrorProcessorType;
-
- PROCEDURE Error (err: INTEGER);
- (*-------------------------------------------------------*
- * Error gibt eine Fehlermeldung in Abhängigkeit von der *
- * Fehlernummer aus in der Form: *
- * 'Fehler Nr. <nr> in Zeile <xx> Spalte <yy>. *
- * < Fehlerbeschreibung > *
- * Die Ausgabe erfolgt in das zuvor definierte debug. *
- * Die Fehlerbeschreibung befindet sich in der Datei *
- * ERRORS.TXT. Der Programmlauf wird beendet, wenn *
- * stop = TRUE. *
- *-------------------------------------------------------*)
-
- VAR ErrorDescript: Stream;
- i : CARDINAL;
- s : String;
- reply : INTEGER;
-
- BEGIN
- IF err<0 THEN err:=-err
- ELSIF err>0 THEN
- OpenStream (ErrorDescript, ErrorText, READ, reply);
- WRiteString (debug, 'Fehler Nr. ');
- WRiteCard (debug, err, 4);
- (* An dieser Stelle kann die Ausgabe der Zeile und *)
- (* Spalte erfolgen, an der der Fehler auftrat. *)
- (* line und column wurden aus dem Lesemodul importiert. *)
- (* WRiteString (debug, ' in Zeile ' ); *)
- (* WRiteCard (debug, line , 4); *)
- (* WRiteString (debug, ' , Spalte ' ); *)
- (* WRiteCard (debug, column,4); *)
- WRite (debug, '.'); WRiteLn (debug);
- FOR i:=1 TO err DO
- IF NOT EOS(ErrorDescript) THEN
- REadString (ErrorDescript, s)
- END;
- END;
- IF EOS (ErrorDescript) THEN Assign (s,'') END;
- Message (s);
- IF stop THEN HALT END;
- END;
- END Error;
-
- (*-------------------------------------------------------*
- * Typen für Debugging *
- *-------------------------------------------------------*)
-
- TYPE (* Typen-Konvertierung: *)
- ByteType = RECORD
- CASE : CHAR OF
- 'a': Byte: BYTE; |
- 'b': Char: CHAR; |
- 'c': Bool: BOOLEAN; |
- 'd': Set : SET OF [0..7]; |
- END;
- END;
-
- WordType = RECORD
- CASE : CHAR OF
- 'a': Word : WORD; |
- 'b': Integer : INTEGER; |
- 'c': Cardinal: CARDINAL; |
- 'd': Set : SET OF [0..15]; |
- END;
- END;
-
- LongWordType = RECORD
- CASE : CHAR OF
- 'a': LongWord : LONGWORD; |
- 'b': Address : ADDRESS; |
- 'c': Real : REAL; |
- 'd': Set : SET OF [0..31];|
- END;
- END;
-
- SubType = RECORD
- CASE : BOOLEAN OF
- TRUE : Long : LONGCARD; |
- FALSE: c1,c2: CARDINAL; |
- END;
- END;
-
-
- PROCEDURE ErrorProc;
-
- VAR err: ErrorContextType;
- i: INTEGER;
-
- BEGIN
- err:=ErrorContext;
- Error (err.Error+70);
- WRiteString (debug, 'Error came from: ');
- CASE err.CameFrom OF
- XError : WRiteString (debug,'XError'); |
- XRaise : WRiteString (debug,'XRaise'); |
- XPropagate : WRiteString (debug,'xPropagate');|
- END;
- WRiteLn (debug); WRiteLn (debug);
- Message ('Processor Status:');
- ShowLong ('PC', err.PC);
- ShowWord ('SR', err.SR);
- ShowLong ('A5', err.A5);
- ShowLong ('A6', err.A6);
- ShowLong ('A7', err.A7);
- Message ('Program terminated by Debugger.');
- CloseStream (debug,i);
- NormalError;
- END ErrorProc;
-
-
- PROCEDURE InitDebugger (VAR name: ARRAY OF CHAR);
- (*-------------------------------------------------------*
- * InitDebugger initialisiert und aktiviert den Debugger.*
- * Hier wird der Debug-Stream eröffnet und der normale *
- * ErrorProzessor des Moduls GEMX überschrieben. *
- * Die Variable name gibt den Dateinamen an. *
- *-------------------------------------------------------*)
-
- VAR
- i: INTEGER;
- c: CHAR;
- s: SubType;
-
- BEGIN
- IF Length(name)=0 THEN name:='CON:'; END;
- Assign (debugname,name);
- OpenStream (debug, name, READWRITE, i);
- init:=(i=0);
- IF init THEN
- NormalError :=ErrorProcessor;
- ErrorProcessor:=ErrorProc;
- active:=TRUE;
- SNr:=0;
- WRiteString (debug,'Calls, Var ');
- WRiteString (debug,' HEX-Val ');
- WRiteString (debug,' DEC-Val ');
- WRiteString (debug,'CHAR,INT,REAL');
- WRiteString (debug,' Bits');
- WRiteLn (debug);
- ELSE
- WRiteString (out,'Debugger-File nicht geöffnet!');
- WRiteString (' Fehler: ');
- WRiteInt (out,i,1); WRiteLn (out);
- REad (in,c);
- HALT;
- END;
- END InitDebugger;
-
- PROCEDURE Activate (act: BOOLEAN);
- (*-------------------------------------------------------*
- * Activate schaltet den Debugger-Modus ein (TRUE) oder *
- * aus (FALSE). *
- *-------------------------------------------------------*)
-
- VAR i: INTEGER;
-
- BEGIN
- IF (NOT active) & act THEN
- InitDebugger (debugname)
- ELSIF active & (NOT act) THEN
- CloseStream (debug,i)
- END;
- active:=act;
- END Activate;
-
- PROCEDURE Into (VAR WhatRoutine: ARRAY OF CHAR);
- (*-------------------------------------------------------*
- * Zeigt den Eintritt in eine Prozedur an. Information *
- * der Form: "I: <WhatRoutine>" wird in den Debug-Stream *
- * geschrieben. *
- *-------------------------------------------------------*)
-
- VAR i,j: CARDINAL;
-
- BEGIN
- INC (SNr);
- IF active THEN
- IF SNr>60 THEN j:=60 ELSE j:=SNr END;
- FOR i:=0 TO j DO
- WRite (debug,' ');
- END;
- WRiteString (debug, 'I: '); Message ( WhatRoutine );
- END;
- END Into;
-
- PROCEDURE Leaving (VAR WhatRoutine: ARRAY OF CHAR);
- (*-------------------------------------------------------*
- * Zeigt den Austritt aus einer Prozedur an. Information *
- * der Form: "L: <WhatRoutine>" wird in den Debug-Stream *
- * geschrieben. *
- *-------------------------------------------------------*)
-
- VAR i,j: CARDINAL;
-
- BEGIN
- IF active THEN
- IF SNr>60 THEN j:=60 ELSE j:=SNr END;
- FOR i:=0 TO j DO
- WRite (debug,' ');
- END;
- WRiteString (debug, 'L: '); Message ( WhatRoutine );
- END;
- DEC (SNr);
- IF SNr<1 THEN SNr:=1; END;
- END Leaving;
-
- PROCEDURE Message (VAR mess: ARRAY OF CHAR);
- (*-------------------------------------------------------*
- * Ausgabe des Strings mess in den Debugger-Stream. *
- *-------------------------------------------------------*)
-
- BEGIN
- IF active THEN
- WRiteString (debug, mess);
- WRiteLn (debug);
- END;
- END Message;
-
-
- PROCEDURE WriteName (VAR name: ARRAY OF CHAR);
-
- VAR i: CARDINAL;
-
- BEGIN
- WRiteString (debug,name);
- IF Length(name)<9 THEN
- FOR i:=Length(name) TO 9 DO WRite (debug,' '); END;
- END;
- WRiteString (debug,'=');
- END WriteName;
-
- PROCEDURE ShowByte (VAR name: ARRAY OF CHAR; byte: BYTE);
- (*-------------------------------------------------------*
- * Ausgabe von Name und Inhalt einer Variablen der Größe *
- * von einem Byte: CHAR, BYTE, SET OF 0..7, BOOLEAN *
- *-------------------------------------------------------*)
-
- VAR
- b: ByteType;
- i: CARDINAL;
-
- BEGIN
- IF active THEN
- b.Byte:=byte;
- WriteName (name);
- WITH b DO
- i:=ORD(Char);
- WRiteHex (debug,i, 9); WRiteString (debug,' ');
- WRiteCard(debug,i,12); WRiteString (debug,' ');
- WRite (debug,'"');
- IF i>30 THEN WRite (debug,Char);
- ELSE WRite (debug,' '); END;
- WRiteString (debug,'" ');
- IF Bool THEN WRiteString (debug,' TRUE ')
- ELSE WRiteString (debug,'FALSE ') END;
- FOR i:=7 TO 0 BY -1 DO
- IF i IN Set THEN WRite (debug,'1')
- ELSE WRite (debug,'0') END
- END;
- END;
- WRiteLn (debug);
- END;
- END ShowByte;
-
- PROCEDURE ShowWord (VAR name: ARRAY OF CHAR; word: WORD);
- (*-------------------------------------------------------*
- * Ausgabe von Name und Inhalt einer Variablen der Größe *
- * von einem Word: INTEGER, CARDINAL, WORD *
- *-------------------------------------------------------*)
-
- VAR
- w: WordType;
- i: CARDINAL;
-
- BEGIN
- IF active THEN
- w.Word:=word;
- WriteName (name);
- WITH w DO
- WRiteHex (debug,Cardinal, 9);
- WRiteString (debug,' ');
- WRiteCard(debug,Cardinal,12);
- WRiteString (debug,' ');
- WRiteInt (debug,Integer ,11);
- WRiteString (debug,'I ');
- FOR i:=15 TO 0 BY-1 DO
- IF i IN Set THEN WRite (debug,'1')
- ELSE WRite (debug,'0') END
- END;
- END;
- WRiteLn (debug);
- END;
- END ShowWord;
-
- PROCEDURE ShowLong (VAR name: ARRAY OF CHAR;
- long: LONGWORD);
- (*-------------------------------------------------------*
- * Ausgabe von Name und Inhalt einer Variablen der Größe *
- * von einem LONGWORD: LONGWORD, LONGINT, LONGCARD, REAL *
- *-------------------------------------------------------*)
-
- VAR
- w: LongWordType;
- i,j: CARDINAL;
- n1,n2: ARRAY[1..20] OF CHAR;
-
- BEGIN
- IF active THEN
- w.LongWord:=long;
- WriteName (name);
- WITH w DO
- WRiteHexAdr (debug, Address, 9);
- WRiteString (debug,' ');
- WRiteAdr (debug, Address,12);
- WRiteString (debug,' ');
- WRiteReal (debug,Real,12,-1);
- WRiteString (debug,' ');
- FOR i:=31 TO 0 BY -1 DO
- IF i IN Set THEN WRite (debug,'1')
- ELSE WRite (debug,'0') END
- END;
- END;
- WRiteLn (debug);
- END;
- END ShowLong;
-
- BEGIN (* Debugger *)
- stop :=FALSE;
- init :=FALSE;
- active:=FALSE;
- Assign (debugname,'CON:');
- END Debugger.