389 fixedName = frame.f_code.co_filename |
391 fixedName = frame.f_code.co_filename |
390 # update cache |
392 # update cache |
391 self._fnCache[fn] = fixedName |
393 self._fnCache[fn] = fixedName |
392 return fixedName |
394 return fixedName |
393 |
395 |
394 def set_watch(self, cond, temporary=False): |
|
395 """ |
|
396 Public method to set a watch expression. |
|
397 |
|
398 @param cond expression of the watch expression (string) |
|
399 @param temporary flag indicating a temporary watch expression (boolean) |
|
400 """ |
|
401 bp = bdb.Breakpoint("Watch", 0, temporary, cond) |
|
402 if cond.endswith('??created??') or cond.endswith('??changed??'): |
|
403 bp.condition, bp.special = cond.split() |
|
404 else: |
|
405 bp.condition = cond |
|
406 bp.special = "" |
|
407 bp.values = {} |
|
408 if "Watch" not in self.breaks: |
|
409 self.breaks["Watch"] = 1 |
|
410 else: |
|
411 self.breaks["Watch"] += 1 |
|
412 |
|
413 def clear_watch(self, cond): |
|
414 """ |
|
415 Public method to clear a watch expression. |
|
416 |
|
417 @param cond expression of the watch expression to be cleared (string) |
|
418 """ |
|
419 try: |
|
420 possibles = bdb.Breakpoint.bplist["Watch", 0] |
|
421 for i in range(0, len(possibles)): |
|
422 b = possibles[i] |
|
423 if b.cond == cond: |
|
424 b.deleteMe() |
|
425 self.breaks["Watch"] -= 1 |
|
426 if self.breaks["Watch"] == 0: |
|
427 del self.breaks["Watch"] |
|
428 break |
|
429 except KeyError: |
|
430 pass |
|
431 |
|
432 def get_watch(self, cond): |
|
433 """ |
|
434 Public method to get a watch expression. |
|
435 |
|
436 @param cond expression of the watch expression to be cleared (string) |
|
437 @return reference to the watch point |
|
438 """ |
|
439 possibles = bdb.Breakpoint.bplist["Watch", 0] |
|
440 for i in range(0, len(possibles)): |
|
441 b = possibles[i] |
|
442 if b.cond == cond: |
|
443 return b |
|
444 |
|
445 def __do_clearWatch(self, cond): |
|
446 """ |
|
447 Private method called to clear a temporary watch expression. |
|
448 |
|
449 @param cond expression of the watch expression to be cleared (string) |
|
450 """ |
|
451 self.clear_watch(cond) |
|
452 self._dbgClient.write('{0}{1}\n'.format(ResponseClearWatch, cond)) |
|
453 |
|
454 def __effective(self, frame): |
|
455 """ |
|
456 Private method to determine, if a watch expression is effective. |
|
457 |
|
458 @param frame the current execution frame |
|
459 @return tuple of watch expression and a flag to indicate, that a |
|
460 temporary watch expression may be deleted (bdb.Breakpoint, boolean) |
|
461 """ |
|
462 possibles = bdb.Breakpoint.bplist["Watch", 0] |
|
463 for i in range(0, len(possibles)): |
|
464 b = possibles[i] |
|
465 if not b.enabled: |
|
466 continue |
|
467 if not b.cond: |
|
468 # watch expression without expression shouldn't occur, |
|
469 # just ignore it |
|
470 continue |
|
471 try: |
|
472 val = eval(b.condition, frame.f_globals, frame.f_locals) |
|
473 if b.special: |
|
474 if b.special == '??created??': |
|
475 if b.values[frame][0] == 0: |
|
476 b.values[frame][0] = 1 |
|
477 b.values[frame][1] = val |
|
478 return (b, True) |
|
479 else: |
|
480 continue |
|
481 b.values[frame][0] = 1 |
|
482 if b.special == '??changed??': |
|
483 if b.values[frame][1] != val: |
|
484 b.values[frame][1] = val |
|
485 if b.values[frame][2] > 0: |
|
486 b.values[frame][2] -= 1 |
|
487 continue |
|
488 else: |
|
489 return (b, True) |
|
490 else: |
|
491 continue |
|
492 continue |
|
493 if val: |
|
494 if b.ignore > 0: |
|
495 b.ignore -= 1 |
|
496 continue |
|
497 else: |
|
498 return (b, True) |
|
499 except Exception: |
|
500 if b.special: |
|
501 try: |
|
502 b.values[frame][0] = 0 |
|
503 except KeyError: |
|
504 b.values[frame] = [0, None, b.ignore] |
|
505 continue |
|
506 |
|
507 return (None, False) |
|
508 |
|
509 def break_here(self, frame): |
396 def break_here(self, frame): |
510 """ |
397 """ |
511 Public method reimplemented from bdb.py to fix the filename from the |
398 Public method reimplemented from bdb.py to fix the filename from the |
512 frame. |
399 frame. |
513 |
400 |
514 See fix_frame_filename for more info. |
401 See fix_frame_filename for more info. |
515 |
402 |
516 @param frame the frame object |
403 @param frame the frame object |
517 @return flag indicating the break status (boolean) |
404 @type frame object |
|
405 @return flag indicating the break status |
|
406 @rtype bool |
518 """ |
407 """ |
519 filename = self.fix_frame_filename(frame) |
408 filename = self.fix_frame_filename(frame) |
520 if filename not in self.breaks and "Watch" not in self.breaks: |
409 if (filename, frame.f_lineno) in Breakpoint.breaks: |
521 return False |
410 bp, flag = Breakpoint.effectiveBreak( |
522 |
411 filename, frame.f_lineno, frame) |
523 if filename in self.breaks: |
412 if bp: |
524 lineno = frame.f_lineno |
|
525 if lineno not in self.breaks[filename]: |
|
526 # The line itself has no breakpoint, but maybe the line is the |
|
527 # first line of a function with breakpoint set by function |
|
528 # name. |
|
529 lineno = frame.f_code.co_firstlineno |
|
530 if lineno in self.breaks[filename]: |
|
531 # flag says ok to delete temp. bp |
413 # flag says ok to delete temp. bp |
532 (bp, flag) = bdb.effective(filename, lineno, frame) |
414 if flag and bp.temporary: |
533 if bp: |
415 self.__do_clearBreak(filename, frame.f_lineno) |
534 self.currentbp = bp.number |
416 return True |
535 if (flag and bp.temporary): |
417 |
536 self.__do_clear(filename, lineno) |
418 if Watch.watches != []: |
537 return True |
419 bp, flag = Watch.effectiveWatch(frame) |
538 |
|
539 if "Watch" in self.breaks: |
|
540 # flag says ok to delete temp. bp |
|
541 (bp, flag) = self.__effective(frame) |
|
542 if bp: |
420 if bp: |
543 self.currentbp = bp.number |
421 # flag says ok to delete temp. watch |
544 if (flag and bp.temporary): |
422 if flag and bp.temporary: |
545 self.__do_clearWatch(bp.cond) |
423 self.__do_clearWatch(bp.cond) |
546 return True |
424 return True |
547 |
425 |
548 return False |
426 return False |
549 |
427 |
553 |
431 |
554 These speciality is to fix the filename from the frame |
432 These speciality is to fix the filename from the frame |
555 (see fix_frame_filename for more info). |
433 (see fix_frame_filename for more info). |
556 |
434 |
557 @param frame the frame object |
435 @param frame the frame object |
558 @return flag indicating the break status (boolean) |
436 @param frame object |
559 """ |
437 @return flag indicating the break status |
560 return \ |
438 @rtype bool |
561 self.fix_frame_filename(frame) in self.breaks or \ |
439 """ |
562 ("Watch" in self.breaks and self.breaks["Watch"]) |
440 return self.fix_frame_filename(frame) in Breakpoint.breakInFile |
563 |
441 |
564 def set_break(self, filename, lineno, temporary=0, cond=None, |
442 def __do_clearBreak(self, filename, lineno): |
565 funcname=None): |
443 """ |
566 """ |
444 Private method called to clear a temporary breakpoint. |
567 Public method reimplemented from bdb.py to normalize the filename and |
445 |
568 set as a breakpoint. |
446 @param filename name of the file the bp belongs to |
569 |
|
570 @param filename the filename where a breakpoint is set |
|
571 @type str |
447 @type str |
572 @param lineno the line number of the breakpoint |
448 @param lineno linenumber of the bp |
573 @type int |
449 @type int |
574 @keyparam temporary flag to indicate a temporary breakpoint |
450 """ |
575 @type int |
451 Breakpoint.clear_break(filename, lineno) |
576 @keyparam cond Python expression which dynamically enables this bp |
452 self._dbgClient.write('%s%s,%d\n' % (ResponseClearBreak, filename, |
|
453 lineno)) |
|
454 |
|
455 def __do_clearWatch(self, cond): |
|
456 """ |
|
457 Private method called to clear a temporary watch expression. |
|
458 |
|
459 @param cond expression of the watch expression to be cleared |
577 @type str |
460 @type str |
578 @keyparam funcname name of the function (unused) |
461 """ |
579 @type str or None |
462 Watch.clear_watch(cond) |
580 """ |
463 self._dbgClient.write('%s%s\n' % (ResponseClearWatch, cond)) |
581 filename = os.path.abspath(filename) |
|
582 list = self.breaks.setdefault(filename, []) |
|
583 if lineno not in list: |
|
584 list.append(lineno) |
|
585 bdb.Breakpoint(filename, lineno, temporary, cond, funcname) |
|
586 |
|
587 def get_break(self, filename, lineno): |
|
588 """ |
|
589 Public method reimplemented from bdb.py to get the first breakpoint of |
|
590 a particular line. |
|
591 |
|
592 Because eric6 supports only one breakpoint per line, this overwritten |
|
593 method will return this one and only breakpoint. |
|
594 |
|
595 @param filename the filename of the bp to retrieve |
|
596 @type str |
|
597 @param lineno the linenumber of the bp to retrieve |
|
598 @type int |
|
599 @return breakpoint or None, if there is no bp |
|
600 @rtype breakpoint object or None |
|
601 """ |
|
602 return (lineno in self.breaks.get(filename, []) and |
|
603 bdb.Breakpoint.bplist[filename, lineno][0] or None) |
|
604 |
|
605 def clear_break(self, filename, lineno): |
|
606 """ |
|
607 Public method reimplemented from bdb.py to clear a breakpoint. |
|
608 |
|
609 @param filename the filename of the bp to retrieve |
|
610 @type str |
|
611 @param lineno the linenumber of the bp to retrieve |
|
612 @type int |
|
613 """ |
|
614 if (filename, lineno) not in bdb.Breakpoint.bplist: |
|
615 return |
|
616 # If there's only one bp in the list for that file,line |
|
617 # pair, then remove the breaks entry |
|
618 for bp in bdb.Breakpoint.bplist[filename, lineno][:]: |
|
619 bp.deleteMe() |
|
620 self._prune_breaks(filename, lineno) |
|
621 |
|
622 def __do_clear(self, filename, lineno): |
|
623 """ |
|
624 Private method called to clear a temporary breakpoint. |
|
625 |
|
626 @param filename name of the file the bp belongs to |
|
627 @param lineno linenumber of the bp |
|
628 """ |
|
629 self.clear_break(filename, lineno) |
|
630 self._dbgClient.write('{0}{1},{2:d}\n'.format( |
|
631 ResponseClearBreak, filename, lineno)) |
|
632 |
464 |
633 def getStack(self): |
465 def getStack(self): |
634 """ |
466 """ |
635 Public method to get the stack. |
467 Public method to get the stack. |
636 |
468 |