home *** CD-ROM | disk | FTP | other *** search
- (*********************************************************)
- (* ERROR.PAS *)
- (* Abfangen von Laufzeit-Fehlern unter Turbo-Pascal 4.0 *)
- (* (c) 1988 Karsten Gieselmann & PASCAL International *)
- (* !!! Die UNIT muß als letzte der UNITs in der USES- *)
- (* !!! Anweisung aufgeführt werden, welche selbst eine *)
- (* !!! Exit-Routine installieren. *)
- (*********************************************************)
-
- UNIT Error;
-
- INTERFACE
-
- VAR
- ContinueAfterError :BOOLEAN;
- (* soll das Prog. nach Fehlerbehandlung weiterlaufen? *)
-
- ErrorsToHandle :SET OF BYTE;
- (* die Codes der abzufangenden Fehler (s. Handbuch) *)
-
- (* übergibt die Fehlerbehandlung einer benutzerdefi-
- nierten Routine der Syntax
- "PROCEDURE xyz (Number :BYTE; Address :POINTER)",
- wobei "Number" die Fehlernummer und "Address" die Feh-
- leradresse bedeuten. Diese vom Benutzer eingesetzte
- Routine muß unbedingt im FAR-Modell kompiliert werden
- ({$F+}-Option) ! *)
- PROCEDURE SetErrorHandler (UserProc :POINTER);
-
- (* übergibt die Fehlerbehandlung der Standardroutine
- dieser UNIT *)
- PROCEDURE ResetErrorHandler;
-
-
- IMPLEMENTATION
-
- VAR
- ExitSave, (* Zeiger auf nächste Exit-Rout.*)
- ErrorHandler :POINTER; (* Zeiger auf Fehlerbehandlung *)
- MainCSeg :WORD; (* Code-Segment des Hauptprog. *)
-
- (* die nächsten beiden Prozeduren müssen FAR kompiliert
- werden! *)
- {$F+}
-
- PROCEDURE DefaultHandler (Number :BYTE; Address :POINTER);
-
- BEGIN
- WriteLn;
- WriteLn ('Laufzeit-Fehler Nr.', Number, ' aufgetreten!');
- END;
-
-
- PROCEDURE ErrorExit;
-
- PROCEDURE CallErrorHandler(Number:BYTE; Address:POINTER);
- INLINE ($FF/$1E/ErrorHandler);
-
- PROCEDURE PatchReturnAddress;
- INLINE ($C4/$16/ErrorAddr/$8C/$C0/$03/$06/MainCSeg/
- $89/$46/$04/$89/$56/$02);
-
- BEGIN
- IF ExitCode in ErrorsToHandle THEN BEGIN
- (* Fehlerbehandlung *)
- CallErrorHandler (ExitCode, ErrorAddr);
- IF ContinueAfterError THEN BEGIN (* Rücksprung zur *)
- PatchReturnAddress; (* Fehleradresse! *)
- ExitCode := 0; (* so tun, als ob kein *)
- ErrorAddr := NIL; (* Fehler gewesen wäre.*)
- ExitProc := @ErrorExit; (* Exit-Zeiger wieder *)
- END (* auf diese Routine. *)
- ELSE
- ExitProc := ExitSave;
- END
- ELSE
- ExitProc := ExitSave; (* Fehler nicht abfangen, Ende *)
- END;
-
- {$F-}
-
- PROCEDURE SetErrorHandler (UserProc :POINTER);
-
- BEGIN
- ErrorHandler := UserProc;
- END;
-
-
- PROCEDURE ResetErrorHandler;
-
- BEGIN
- ErrorHandler := @DefaultHandler;
- END;
-
- (* Unit initialisieren: *)
- BEGIN
- ContinueAfterError := TRUE; (* Defaultwerte setzen *)
- (* nur Floating-Point-Fehler: *)
- ErrorsToHandle := [200,205..207];
- ResetErrorHandler; (* Standardbehandlung der UNIT *)
- (* Fehlerroutine in Exit-Kette einklinken: *)
- ExitSave := ExitProc;
- ExitProc := @ErrorExit;
- (* Offset des Haupt-CS ermitteln: *)
- INLINE ($8B/$46/$02/$A3/MainCSeg);
- END.