+data ActiveBreakPoints
+ = ActiveBreakPoints
+ { breakCounter :: !Int
+ , breakLocations :: ![(Int, BreakLocation)] -- break location uniquely numbered
+ }
+
+instance Outputable ActiveBreakPoints where
+ ppr activeBrks = prettyLocations $ breakLocations activeBrks
+
+emptyActiveBreakPoints :: ActiveBreakPoints
+emptyActiveBreakPoints
+ = ActiveBreakPoints { breakCounter = 0, breakLocations = [] }
+
+data BreakLocation
+ = BreakLocation
+ { breakModule :: !GHC.Module
+ , breakLoc :: !SrcSpan
+ , breakTick :: {-# UNPACK #-} !Int
+ }
+ deriving Eq
+
+prettyLocations :: [(Int, BreakLocation)] -> SDoc
+prettyLocations [] = text "No active breakpoints."
+prettyLocations locs = vcat $ map (\(i, loc) -> brackets (int i) <+> ppr loc) $ reverse $ locs
+
+instance Outputable BreakLocation where
+ ppr loc = (ppr $ breakModule loc) <+> ppr (breakLoc loc)
+
+getActiveBreakPoints :: GHCi ActiveBreakPoints
+getActiveBreakPoints = liftM breaks getGHCiState
+
+-- don't reset the counter back to zero?
+discardActiveBreakPoints :: GHCi ()
+discardActiveBreakPoints = do
+ st <- getGHCiState
+ let oldActiveBreaks = breaks st
+ newActiveBreaks = oldActiveBreaks { breakLocations = [] }
+ setGHCiState $ st { breaks = newActiveBreaks }
+
+deleteBreak :: Int -> GHCi ()
+deleteBreak identity = do
+ st <- getGHCiState
+ let oldActiveBreaks = breaks st
+ oldLocations = breakLocations oldActiveBreaks
+ newLocations = filter (\loc -> fst loc /= identity) oldLocations
+ newActiveBreaks = oldActiveBreaks { breakLocations = newLocations }
+ setGHCiState $ st { breaks = newActiveBreaks }
+
+recordBreak :: BreakLocation -> GHCi (Bool{- was already present -}, Int)
+recordBreak brkLoc = do
+ st <- getGHCiState
+ let oldActiveBreaks = breaks st
+ let oldLocations = breakLocations oldActiveBreaks
+ -- don't store the same break point twice
+ case [ nm | (nm, loc) <- oldLocations, loc == brkLoc ] of
+ (nm:_) -> return (True, nm)
+ [] -> do
+ let oldCounter = breakCounter oldActiveBreaks
+ newCounter = oldCounter + 1
+ newActiveBreaks =
+ oldActiveBreaks
+ { breakCounter = newCounter
+ , breakLocations = (oldCounter, brkLoc) : oldLocations
+ }
+ setGHCiState $ st { breaks = newActiveBreaks }
+ return (False, oldCounter)
+