Commits

riaan  committed 7efa4ef

Added adjustBreakpoints method. This allows breakpoints to change lineno.

  • Participants
  • Parent commits 00adbdc

Comments (0)

Files changed (3)

File Debugger/Breakpoint.py

 
 class FileBreakpointList:
     def __init__(self):
-        self.lines = {}  # lineno -> [{'temporary', 'cond', 'enabled'}]
+        self.lines = {}  # lineno -> [{'temporary', 'cond', 'enabled', 'ignore'}]
 
     def loadBreakpoints(self, fn):
         try:
             del self.lines[lineno]
             self.lines[lineno] = bp
 
+    def adjustBreakpoints(self, lineno, delta):
+        set_breaks = []
+        # traverse list twice, first deleting then re-adding to avoid stepping 
+        # on our own toes
+        for brklineno, breaks in self.lines.items():
+            if lineno < brklineno-1:
+                del self.lines[brklineno]
+                set_breaks.append( (brklineno+delta, breaks) )
+        for brklineno, breaks in set_breaks:
+            self.lines[brklineno] = breaks
+
     def enableBreakpoints(self, lineno, enable=1):
         if self.lines.has_key(lineno):
             linebreaks = self.lines[lineno]
                 rval.append(brkinfo)
         return rval
 
-    def hasBreakpoint(self, lineno):
-        return self.lines.has_key(lineno)
+    def hasBreakpoint(self, lineno, endlineno=-1):
+        if endlineno < 0:
+            return self.lines.has_key(lineno)
+        else:
+            for line in self.lines.keys():
+                if line >= lineno and line <= endlineno:
+                    return 1
+            return 0
 
     def clearTemporaryBreakpoints(self, lineno):
         if self.lines.has_key(lineno):
         filename = self.normalize(filename)
         if self.files.has_key(filename):
             filelist = self.files[filename]
-            filelist.moveBreakpoint(lineno)
+            filelist.moveBreakpoint(lineno, newlineno)
+
+    def adjustBreakpoints(self, filename, lineno, delta):
+        if self.files.has_key(filename):
+            filelist = self.files[filename]
+            return filelist.adjustBreakpoints(lineno, delta)
+        return 0
 
     def enableBreakpoints(self, filename, lineno, enable=1):
         filename = self.normalize(filename)
             self.files[filename] = filelist = FileBreakpointList()
             return filelist
 
-    def hasBreakpoint(self, filename, lineno):
+    def hasBreakpoint(self, filename, lineno, endlineno=-1):
         filename = self.normalize(filename)
         if self.files.has_key(filename):
             filelist = self.files[filename]
-            return filelist.hasBreakpoint(lineno)
+            return filelist.hasBreakpoint(lineno, endlineno)
         return 0
 
     def getBreakpointList(self, fn=None):

File Debugger/Debugger.py

         self.invokeInDebugger('clearBreakpoints', (fn, lineno))
         self.breakpts.refreshList()
 
+    def adjustBreakpoints(self, filename, lineno, delta):
+        fn = self.clientFNToServerFN(filename)
+        self.invokeInDebugger('adjustBreakpoints', (fn, lineno, delta))
+        self.breakpts.refreshList()
+
     def setBreakpoint(self, filename, lineno, tmp):
         fn = self.clientFNToServerFN(filename)
         self.invokeInDebugger('addBreakpoint', (fn, lineno, tmp))

File Debugger/IsolatedDebugger.py

 class DebugError(Exception):
     """Incorrect operation of the debugger"""
 
+class BreakpointError(DebugError):
+    """Incorrect operation on a breakpoint"""
 
 
 class DebuggerConnection:
         self._ds.conditionalBreakpoints(filename, lineno, cond)
 
     def clearBreakpoints(self, filename, lineno):
-        """Clears all breakpoints on a line.  Non-blocking and immediate.
+        """Clears all breakpoints on a line.  
+        Non-blocking and immediate.
         """
         self._ds.clearBreakpoints(filename, lineno)
 
+    def adjustBreakpoints(self, filename, lineno, delta):
+        """Moves all applicable breakpoints when delta lines are added or 
+        deleted.  
+        Non-blocking and immediate.
+        """
+        self._ds.adjustBreakpoints(filename, lineno, delta)
+
     ### Blocking methods.
 
     def pprintVarValue(self, name, frameno):
         bp = self.set_break(filename, lineno, temporary, cond)
         if type(bp) == type(''):
             # Note that checking for string type is strange. Argh.
-            raise DebugError(bp)
+            raise BreakpointError(bp)
         elif bp is not None and not enabled:
             bp.disable()
         bp.ignore = ignore
         Non-blocking.
         """
         bps = self.get_breaks(filename, lineno)
-        print 'ignoreBreakpoints', filename, self.breaks.keys(), bps
         if bps:
             for bp in bps:
                 bp.ignore = ignore
                 bp.cond = cond
 
     def clearBreakpoints(self, filename, lineno):
-        """Clears all breakpoints on a line.  Non-blocking.
+        """Clears all breakpoints on a line.
+        Non-blocking.
         """
         msg = self.clear_break(filename, lineno)
         if msg is not None:
-            raise DebugError(msg)
+            raise BreakpointError(msg)
+
+    def adjustBreakpoints(self, filename, lineno, delta):
+        """Moves all applicable breakpoints when delta lines are added or 
+        deleted. 
+        Non-blocking.
+        """
+        ## This can be more efficient, but for now sticking to the bdb interface
+        # Unfortunately this must be done on a low level
+        filename = self.canonic(filename)
+        breaklines = self.get_file_breaks(filename)
+        bplist = bdb.Breakpoint.bplist
+        set_breaks = []
+        # store reference and remove from (fn, ln) refed dict.
+        for line in breaklines[:]:
+            if line > lineno:
+                set_breaks.append(self.get_breaks(filename, line))
+                breaklines.remove(line)
+                del bplist[filename, line]
+        # put old break at new place and renumber
+        for brks in set_breaks:
+            for brk in brks:
+                brk.line = brk.line + delta
+                breaklines.append(brk.line)
+                # merge in moved breaks
+                if bplist.has_key((filename, brk.line)):
+                    bplist[filename, brk.line].append(brk)
+                else:
+                    bplist[filename, brk.line] = [brk]
+        # reorder lines
+        breaklines.sort()
 
     def getStackInfo(self):
         try:
         rval = []
         for bps in bdb.Breakpoint.bplist.values():
             for bp in bps:
-                #filename = getattr(bp, 'orig_filename', bp.file)
                 filename = bp.file  # Already canonic
                 rval.append({'filename':filename,
                              'lineno':bp.line,