<<>> <> <> <> <<>> DIRECTORY TargetArchitecture, BreakWorldArchitecture, RefTab, Breakpoint, Shepherd, Rope; BreakpointImpl: CEDAR PROGRAM IMPORTS Breakpoint, RefTab, BreakWorldArchitecture EXPORTS Breakpoint, BreakWorldArchitecture ~ { <> BreakAccess: PUBLIC TYPE ~ Breakpoint.BreakAccess _ Breakpoint.nullBreakAccess; BreakAccessRep: PUBLIC TYPE ~ Breakpoint.BreakAccessRep; <> BreakAccessData: PUBLIC TYPE ~ REF BreakAccessDataRep _ Breakpoint.nullBreakAccessData; BreakAccessDataRep: PUBLIC TYPE ~ RECORD [ breakTable: RefTab.Ref _ NIL ]; Break: PUBLIC TYPE ~ REF BreakRep _ Breakpoint.nullBreak; BreakRep: PUBLIC TYPE ~ RECORD [ breakAccess: Breakpoint.BreakAccess, address: BreakWorldArchitecture.Address, patch: Shepherd.Patch, clientData: Breakpoint.ClientData ]; <> NewBreakAccess: PUBLIC PROCEDURE [] RETURNS [Breakpoint.BreakAccess] ~{ procs: Breakpoint.BreakAccessProcs ~ NEW[Breakpoint.BreakAccessProcsRep _ [ set: Breakpoint.SetBreakpoint, clear: Breakpoint.ClearBreakpoint, enumerate: Breakpoint.EnumerateBreakpoints]]; data: Breakpoint.BreakAccessData ~ NEW[BreakAccessDataRep _ [ breakTable: RefTab.Create[]]]; breakAccess: Breakpoint.BreakAccess ~ NEW[Breakpoint.BreakAccessRep _ [procs: procs, data: data]]; RETURN [breakAccess]; }; EnumerateBreakpoints: PUBLIC Breakpoint.EnumerateBreakProc ~ { <> Apply: RefTab.EachPairAction ~ { <> break: Break ~ NARROW[val]; clientData: Breakpoint.ClientData ~ Breakpoint.ClientDataFromBreak[break: break]; quit _ proc[clientData: clientData]; RETURN [quit: quit]; }; breakAccess: Breakpoint.BreakAccess ~ BreakWorldArchitecture.BreakAccessFromBreakWorld[breakWorld: breakWorld]; breakTable: RefTab.Ref ~ BreakTableFromBreakAccess[breakAccess: breakAccess]; IF breakTable = NIL THEN { ERROR Breakpoint.Cant[ code: $NullBreakTable, message: "EnumerateBreakpoints[nullBreakTable]"]; }; quit _ breakTable.Pairs[action: Apply]; RETURN [quit: quit]; }; RememberBreak: PUBLIC PROCEDURE [break: Break] ~ { breakAccess: Breakpoint.BreakAccess ~ BreakAccessFromBreak[break: break]; breakTable: RefTab.Ref ~ BreakTableFromBreakAccess[breakAccess: breakAccess]; IF breakTable = NIL THEN { ERROR Breakpoint.Cant[ code: $NullBreakTable, message: "RememberBreak[nullBreakTable]"]; }; IF NOT breakTable.Insert[key: break, val: break] THEN { ERROR Breakpoint.Cant[code: $CantRememberBreak, message: "Can't remember break"]; }; RETURN; }; ForgetBreak: PUBLIC PROCEDURE [break: Break] ~ { breakAccess: Breakpoint.BreakAccess ~ BreakAccessFromBreak[break: break]; breakTable: RefTab.Ref ~ BreakTableFromBreakAccess[breakAccess: breakAccess]; IF breakTable = NIL THEN { ERROR Breakpoint.Cant[ code: $NullBreakTable, message: "ForgetBreak[nullBreakTable]"]; }; IF NOT breakTable.Delete[key: break] THEN { ERROR Breakpoint.Cant[code: $CantForgetBreak, message: "Can't forget break"]; }; RETURN; }; NewBreak: PUBLIC PROCEDURE [ address: BreakWorldArchitecture.Address, patch: Shepherd.Patch, clientData: Breakpoint.ClientData] RETURNS [Breakpoint.Break] ~ { breakWorld: BreakWorldArchitecture.BreakWorld ~ BreakWorldArchitecture.BreakWorldFromBreakWorldAddress[address: address]; breakAccess: Breakpoint.BreakAccess ~ BreakWorldArchitecture.BreakAccessFromBreakWorld[breakWorld: breakWorld]; break: Breakpoint.Break ~ NEW[BreakRep _ [ breakAccess: breakAccess, address: address, patch: patch, clientData: clientData]]; RETURN [break]; }; IsNullBreak: PUBLIC PROCEDURE [break: Breakpoint.Break] RETURNS [BOOLEAN] ~ { RETURN [break = Breakpoint.nullBreak]; }; AddressFromBreak: PUBLIC PROCEDURE [break: Breakpoint.Break] RETURNS [BreakWorldArchitecture.Address] ~ { IF break.IsNullBreak[] THEN { ERROR Breakpoint.Cant[code: $NullBreak, message: "AddressFromBreak[nullBreak]"]; }; RETURN [break.address]; }; PatchFromBreak: PUBLIC PROCEDURE [break: Breakpoint.Break] RETURNS [Shepherd.Patch] ~ { IF break.IsNullBreak[] THEN { ERROR Breakpoint.Cant[code: $NullBreak, message: "PatchFromBreak[nullBreak]"]; }; RETURN [break.patch]; }; ClientDataFromBreak: PUBLIC PROCEDURE [break: Breakpoint.Break] RETURNS [Breakpoint.ClientData] ~ { IF break.IsNullBreak[] THEN { ERROR Breakpoint.Cant[code: $NullBreak, message: "ClientDataFromBreak[nullBreak]"]; }; RETURN [break.clientData]; }; <> BreakAccessFromBreak: PROCEDURE [break: Break] RETURNS [Breakpoint.BreakAccess] ~ { IF Breakpoint.IsNullBreak[break: break] THEN { ERROR Breakpoint.Cant[ code: $NullBreak, message: "BreakAccessFromBreak[nullBreak]"]; }; RETURN [break.breakAccess]; }; BreakTableFromBreakAccess: PROCEDURE [breakAccess: Breakpoint.BreakAccess] RETURNS [RefTab.Ref] ~ { IF breakAccess = Breakpoint.nullBreakAccess THEN { ERROR Breakpoint.Cant[code: $NullBreakAccess, message: "Null breakAccess"]; }; IF breakAccess.data = Breakpoint.nullBreakAccessData THEN { ERROR Breakpoint.Cant[code: $NullBreakAccessData, message: "Null breakAccess.data"]; }; RETURN [breakAccess.data.breakTable]; }; }. <<>>