⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 db.pm

📁 MSYS在windows下模拟了一个类unix的终端
💻 PM
📖 第 1 页 / 共 2 页
字号:
## Documentation is at the __END__#package DB;# "private" globalsmy ($running, $ready, $deep, $usrctxt, $evalarg,     @stack, @saved, @skippkg, @clients);my $preeval = {};my $posteval = {};my $ineval = {};###### Globals - must be defined at startup so that clients can refer to # them right after a C<require DB;>#####BEGIN {  # these are hardcoded in perl source (some are magical)  $DB::sub = '';        # name of current subroutine  %DB::sub = ();        # "filename:fromline-toline" for every known sub  $DB::single = 0;      # single-step flag (set it to 1 to enable stops in BEGIN/use)  $DB::signal = 0;      # signal flag (will cause a stop at the next line)  $DB::trace = 0;       # are we tracing through subroutine calls?  @DB::args = ();       # arguments of current subroutine or @ARGV array  @DB::dbline = ();     # list of lines in currently loaded file  %DB::dbline = ();     # actions in current file (keyed by line number)  @DB::ret = ();        # return value of last sub executed in list context  $DB::ret = '';        # return value of last sub executed in scalar context  # other "public" globals    $DB::package = '';    # current package space  $DB::filename = '';   # current filename  $DB::subname = '';    # currently executing sub (fullly qualified name)  $DB::lineno = '';     # current line number  $DB::VERSION = $DB::VERSION = '1.0';  # initialize private globals to avoid warnings  $running = 1;         # are we running, or are we stopped?  @stack = (0);  @clients = ();  $deep = 100;  $ready = 0;  @saved = ();  @skippkg = ();  $usrctxt = '';  $evalarg = '';}##### entry point for all subroutine calls#sub sub {  push(@stack, $DB::single);  $DB::single &= 1;  $DB::single |= 4 if $#stack == $deep;#  print $DB::sub, "\n";  if ($DB::sub =~ /(?:^|::)DESTROY$/ or not defined wantarray) {    &$DB::sub;    $DB::single |= pop(@stack);    $DB::ret = undef;  }  elsif (wantarray) {    @DB::ret = &$DB::sub;    $DB::single |= pop(@stack);    @DB::ret;  }  else {    $DB::ret = &$DB::sub;    $DB::single |= pop(@stack);    $DB::ret;  }}##### this is called by perl for every statement#sub DB {  return unless $ready;  &save;  ($DB::package, $DB::filename, $DB::lineno) = caller;  return if @skippkg and grep { $_ eq $DB::package } @skippkg;  $usrctxt = "package $DB::package;";		# this won't let them modify, alas  local(*DB::dbline) = "::_<$DB::filename";  my ($stop, $action);  if (($stop,$action) = split(/\0/,$DB::dbline{$DB::lineno})) {    if ($stop eq '1') {      $DB::signal |= 1;    }    else {      $stop = 0 unless $stop;			# avoid un_init warning      $evalarg = "\$DB::signal |= do { $stop; }"; &eval;      $DB::dbline{$DB::lineno} =~ s/;9($|\0)/$1/;    # clear any temp breakpt    }  }  if ($DB::single || $DB::trace || $DB::signal) {    $DB::subname = ($DB::sub =~ /\'|::/) ? $DB::sub : "${DB::package}::$DB::sub"; #';    DB->loadfile($DB::filename, $DB::lineno);  }  $evalarg = $action, &eval if $action;  if ($DB::single || $DB::signal) {    _outputall($#stack . " levels deep in subroutine calls.\n") if $DB::single & 4;    $DB::single = 0;    $DB::signal = 0;    $running = 0;        &eval if ($evalarg = DB->prestop);    my $c;    for $c (@clients) {      # perform any client-specific prestop actions      &eval if ($evalarg = $c->cprestop);            # Now sit in an event loop until something sets $running      do {	$c->idle;                     # call client event loop; must not block	if ($running == 2) {          # client wants something eval-ed	  &eval if ($evalarg = $c->evalcode);	  $running = 0;	}      } until $running;            # perform any client-specific poststop actions      &eval if ($evalarg = $c->cpoststop);    }    &eval if ($evalarg = DB->poststop);  }  ($@, $!, $,, $/, $\, $^W) = @saved;  ();}  ##### this takes its argument via $evalarg to preserve current @_#    sub eval {  ($@, $!, $,, $/, $\, $^W) = @saved;  eval "$usrctxt $evalarg; &DB::save";  _outputall($@) if $@;}################################################################################         no compile-time subroutine call allowed before this point           ################################################################################use strict;                # this can run only after DB() and sub() are definedsub save {  @saved = ($@, $!, $,, $/, $\, $^W);  $, = ""; $/ = "\n"; $\ = ""; $^W = 0;}sub catch {  for (@clients) { $_->awaken; }  $DB::signal = 1;  $ready = 1;}###### Client callable (read inheritable) methods defined after this point#####sub register {  my $s = shift;  $s = _clientname($s) if ref($s);  push @clients, $s;}sub done {  my $s = shift;  $s = _clientname($s) if ref($s);  @clients = grep {$_ ne $s} @clients;  $s->cleanup;#  $running = 3 unless @clients;  exit(0) unless @clients;}sub _clientname {  my $name = shift;  "$name" =~ /^(.+)=[A-Z]+\(.+\)$/;  return $1;}sub next {  my $s = shift;  $DB::single = 2;  $running = 1;}sub step {  my $s = shift;  $DB::single = 1;  $running = 1;}sub cont {  my $s = shift;  my $i = shift;  $s->set_tbreak($i) if $i;  for ($i = 0; $i <= $#stack;) {	$stack[$i++] &= ~1;  }  $DB::single = 0;  $running = 1;}##### XXX caller must experimentally determine $i (since it depends# on how many client call frames are between this call and the DB call).# Such is life.#sub ret {  my $s = shift;  my $i = shift;      # how many levels to get to DB sub  $i = 0 unless defined $i;  $stack[$#stack-$i] |= 1;  $DB::single = 0;  $running = 1;}##### XXX caller must experimentally determine $start (since it depends# on how many client call frames are between this call and the DB call).# Such is life.#sub backtrace {  my $self = shift;  my $start = shift;  my($p,$f,$l,$s,$h,$w,$e,$r,$a, @a, @ret,$i);  $start = 1 unless $start;  for ($i = $start; ($p,$f,$l,$s,$h,$w,$e,$r) = caller($i); $i++) {    @a = @DB::args;    for (@a) {      s/'/\\'/g;      s/([^\0]*)/'$1'/ unless /^-?[\d.]+$/;      s/([\200-\377])/sprintf("M-%c",ord($1)&0177)/eg;      s/([\0-\37\177])/sprintf("^%c",ord($1)^64)/eg;    }    $w = $w ? '@ = ' : '$ = ';    $a = $h ? '(' . join(', ', @a) . ')' : '';    $e =~ s/\n\s*\;\s*\Z// if $e;    $e =~ s/[\\\']/\\$1/g if $e;    if ($r) {      $s = "require '$e'";    } elsif (defined $r) {      $s = "eval '$e'";    } elsif ($s eq '(eval)') {      $s = "eval {...}";    }    $f = "file `$f'" unless $f eq '-e';    push @ret, "$w&$s$a from $f line $l";    last if $DB::signal;  }  return @ret;}sub _outputall {  my $c;  for $c (@clients) {    $c->output(@_);  }}sub trace_toggle {  my $s = shift;  $DB::trace = !$DB::trace;}##### without args: returns all defined subroutine names# with subname args: returns a listref [file, start, end]#sub subs {  my $s = shift;  if (@_) {    my(@ret) = ();    while (@_) {      my $name = shift;      push @ret, [$DB::sub{$name} =~ /^(.*)\:(\d+)-(\d+)$/] 	if exists $DB::sub{$name};    }    return @ret;  }  return keys %DB::sub;}##### first argument is a filename whose subs will be returned# if a filename is not supplied, all subs in the current# filename are returned.#sub filesubs {  my $s = shift;  my $fname = shift;  $fname = $DB::filename unless $fname;  return grep { $DB::sub{$_} =~ /^$fname/ } keys %DB::sub;}##### returns a list of all filenames that DB knows about#sub files {  my $s = shift;  my(@f) = grep(m|^_<|, keys %main::);  return map { substr($_,2) } @f;}##### returns reference to an array holding the lines in currently# loaded file#sub lines {  my $s = shift;  return \@DB::dbline;}##### loadfile($file, $line)#sub loadfile {  my $s = shift;  my($file, $line) = @_;  if (!defined $main::{'_<' . $file}) {    my $try;    if (($try) = grep(m|^_<.*$file|, keys %main::)) {        $file = substr($try,2);    }  }  if (defined($main::{'_<' . $file})) {    my $c;#    _outputall("Loading file $file..");    *DB::dbline = "::_<$file";    $DB::filename = $file;    for $c (@clients) {#      print "2 ", $file, '|', $line, "\n";      $c->showfile($file, $line);    }    return $file;  }  return undef;}sub lineevents {  my $s = shift;  my $fname = shift;  my(%ret) = ();  my $i;  $fname = $DB::filename unless $fname;  local(*DB::dbline) = "::_<$fname";  for ($i = 1; $i <= $#DB::dbline; $i++) {    $ret{$i} = [$DB::dbline[$i], split(/\0/, $DB::dbline{$i})]       if defined $DB::dbline{$i};  }  return %ret;}sub set_break {  my $s = shift;  my $i = shift;  my $cond = shift;  $i ||= $DB::lineno;  $cond ||= '1';  $i = _find_subline($i) if ($i =~ /\D/);  $s->output("Subroutine not found.\n") unless $i;  if ($i) {    if ($DB::dbline[$i] == 0) {      $s->output("Line $i not breakable.\n");    }    else {      $DB::dbline{$i} =~ s/^[^\0]*/$cond/;    }  }}sub set_tbreak {  my $s = shift;  my $i = shift;  $i = _find_subline($i) if ($i =~ /\D/);  $s->output("Subroutine not found.\n") unless $i;  if ($i) {    if ($DB::dbline[$i] == 0) {      $s->output("Line $i not breakable.\n");    }    else {      $DB::dbline{$i} =~ s/($|\0)/;9$1/; # add one-time-only b.p.    }  }}sub _find_subline {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -