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

📄 deparse.pm

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 PM
📖 第 1 页 / 共 5 页
字号:
	my $sv = $cv->const_sv;	if ($$sv) {	    # uh-oh. inlinable sub... format it differently	    return $proto . "{ " . $self->const($sv, 0) . " }\n";	} else { # XSUB? (or just a declaration)	    return "$proto;\n";	}    }    return $proto ."{\n\t$body\n\b}" ."\n";}sub deparse_format {    my $self = shift;    my $form = shift;    my @text;    local($self->{'curcv'}) = $form;    local($self->{'curcvlex'});    local($self->{'in_format'}) = 1;    local(@$self{qw'curstash warnings hints hinthash'})		= @$self{qw'curstash warnings hints hinthash'};    my $op = $form->ROOT;    my $kid;    return "\f." if $op->first->name eq 'stub'                || $op->first->name eq 'nextstate';    $op = $op->first->first; # skip leavewrite, lineseq    while (not null $op) {	$op = $op->sibling; # skip nextstate	my @exprs;	$kid = $op->first->sibling; # skip pushmark	push @text, "\f".$self->const_sv($kid)->PV;	$kid = $kid->sibling;	for (; not null $kid; $kid = $kid->sibling) {	    push @exprs, $self->deparse($kid, 0);	}	push @text, "\f".join(", ", @exprs)."\n" if @exprs;	$op = $op->sibling;    }    return join("", @text) . "\f.";}sub is_scope {    my $op = shift;    return $op->name eq "leave" || $op->name eq "scope"      || $op->name eq "lineseq"	|| ($op->name eq "null" && class($op) eq "UNOP"	    && (is_scope($op->first) || $op->first->name eq "enter"));}sub is_state {    my $name = $_[0]->name;    return $name eq "nextstate" || $name eq "dbstate" || $name eq "setstate";}sub is_miniwhile { # check for one-line loop (`foo() while $y--')    my $op = shift;    return (!null($op) and null($op->sibling)	    and $op->name eq "null" and class($op) eq "UNOP"	    and (($op->first->name =~ /^(and|or)$/		  and $op->first->first->sibling->name eq "lineseq")		 or ($op->first->name eq "lineseq"		     and not null $op->first->first->sibling		     and $op->first->first->sibling->name eq "unstack")		 ));}# Check if the op and its sibling are the initialization and the rest of a# for (..;..;..) { ... } loopsub is_for_loop {    my $op = shift;    # This OP might be almost anything, though it won't be a    # nextstate. (It's the initialization, so in the canonical case it    # will be an sassign.) The sibling is a lineseq whose first child    # is a nextstate and whose second is a leaveloop.    my $lseq = $op->sibling;    if (!is_state $op and !null($lseq) and $lseq->name eq "lineseq") {	if ($lseq->first && !null($lseq->first) && is_state($lseq->first)	    && (my $sib = $lseq->first->sibling)) {	    return (!null($sib) && $sib->name eq "leaveloop");	}    }    return 0;}sub is_scalar {    my $op = shift;    return ($op->name eq "rv2sv" or	    $op->name eq "padsv" or	    $op->name eq "gv" or # only in array/hash constructs	    $op->flags & OPf_KIDS && !null($op->first)	      && $op->first->name eq "gvsv");}sub maybe_parens {    my $self = shift;    my($text, $cx, $prec) = @_;    if ($prec < $cx              # unary ops nest just fine	or $prec == $cx and $cx != 4 and $cx != 16 and $cx != 21	or $self->{'parens'})    {	$text = "($text)";	# In a unop, let parent reuse our parens; see maybe_parens_unop	$text = "\cS" . $text if $cx == 16;	return $text;    } else {	return $text;    }}# same as above, but get around the `if it looks like a function' rulesub maybe_parens_unop {    my $self = shift;    my($name, $kid, $cx) = @_;    if ($cx > 16 or $self->{'parens'}) {	$kid =  $self->deparse($kid, 1); 	if ($name eq "umask" && $kid =~ /^\d+$/) {	    $kid = sprintf("%#o", $kid);	}	return "$name($kid)";    } else {	$kid = $self->deparse($kid, 16); 	if ($name eq "umask" && $kid =~ /^\d+$/) {	    $kid = sprintf("%#o", $kid);	}	if (substr($kid, 0, 1) eq "\cS") {	    # use kid's parens	    return $name . substr($kid, 1);	} elsif (substr($kid, 0, 1) eq "(") {	    # avoid looks-like-a-function trap with extra parens	    # (`+' can lead to ambiguities)	    return "$name(" . $kid  . ")";	} else {	    return "$name $kid";	}    }}sub maybe_parens_func {    my $self = shift;    my($func, $text, $cx, $prec) = @_;    if ($prec <= $cx or substr($text, 0, 1) eq "(" or $self->{'parens'}) {	return "$func($text)";    } else {	return "$func $text";    }}sub maybe_local {    my $self = shift;    my($op, $cx, $text) = @_;    my $our_intro = ($op->name =~ /^(gv|rv2)[ash]v$/) ? OPpOUR_INTRO : 0;    if ($op->private & (OPpLVAL_INTRO|$our_intro)	and not $self->{'avoid_local'}{$$op}) {	my $our_local = ($op->private & OPpLVAL_INTRO) ? "local" : "our";	if( $our_local eq 'our' ) {	    # XXX This assertion fails code with non-ASCII identifiers,	    # like ./ext/Encode/t/jperl.t	    die "Unexpected our($text)\n" unless $text =~ /^\W(\w+::)*\w+\z/;	    $text =~ s/(\w+::)+//;	}        if (want_scalar($op)) {	    return "$our_local $text";	} else {	    return $self->maybe_parens_func("$our_local", $text, $cx, 16);	}    } else {	return $text;    }}sub maybe_targmy {    my $self = shift;    my($op, $cx, $func, @args) = @_;    if ($op->private & OPpTARGET_MY) {	my $var = $self->padname($op->targ);	my $val = $func->($self, $op, 7, @args);	return $self->maybe_parens("$var = $val", $cx, 7);    } else {	return $func->($self, $op, $cx, @args);    }}sub padname_sv {    my $self = shift;    my $targ = shift;    return $self->{'curcv'}->PADLIST->ARRAYelt(0)->ARRAYelt($targ);}sub maybe_my {    my $self = shift;    my($op, $cx, $text) = @_;    if ($op->private & OPpLVAL_INTRO and not $self->{'avoid_local'}{$$op}) {	my $my = $op->private & OPpPAD_STATE ? "state" : "my";	if (want_scalar($op)) {	    return "$my $text";	} else {	    return $self->maybe_parens_func($my, $text, $cx, 16);	}    } else {	return $text;    }}# The following OPs don't have functions:# pp_padany -- does not exist after parsingsub AUTOLOAD {    if ($AUTOLOAD =~ s/^.*::pp_//) {	warn "unexpected OP_".uc $AUTOLOAD;	return "XXX";    } else {	die "Undefined subroutine $AUTOLOAD called";    }}sub DESTROY {}	#	Do not AUTOLOAD# $root should be the op which represents the root of whatever# we're sequencing here. If it's undefined, then we don't append# any subroutine declarations to the deparsed ops, otherwise we# append appropriate declarations.sub lineseq {    my($self, $root, @ops) = @_;    my($expr, @exprs);    my $out_cop = $self->{'curcop'};    my $out_seq = defined($out_cop) ? $out_cop->cop_seq : undef;    my $limit_seq;    if (defined $root) {	$limit_seq = $out_seq;	my $nseq;	$nseq = $self->find_scope_st($root->sibling) if ${$root->sibling};	$limit_seq = $nseq if !defined($limit_seq)			   or defined($nseq) && $nseq < $limit_seq;    }    $limit_seq = $self->{'limit_seq'}	if defined($self->{'limit_seq'})	&& (!defined($limit_seq) || $self->{'limit_seq'} < $limit_seq);    local $self->{'limit_seq'} = $limit_seq;    $self->walk_lineseq($root, \@ops,		       sub { push @exprs, $_[0]} );    my $body = join(";\n", grep {length} @exprs);    my $subs = "";    if (defined $root && defined $limit_seq && !$self->{'in_format'}) {	$subs = join "\n", $self->seq_subs($limit_seq);    }    return join(";\n", grep {length} $body, $subs);}sub scopeop {    my($real_block, $self, $op, $cx) = @_;    my $kid;    my @kids;    local(@$self{qw'curstash warnings hints hinthash'})		= @$self{qw'curstash warnings hints hinthash'} if $real_block;    if ($real_block) {	$kid = $op->first->sibling; # skip enter	if (is_miniwhile($kid)) {	    my $top = $kid->first;	    my $name = $top->name;	    if ($name eq "and") {		$name = "while";	    } elsif ($name eq "or") {		$name = "until";	    } else { # no conditional -> while 1 or until 0		return $self->deparse($top->first, 1) . " while 1";	    }	    my $cond = $top->first;	    my $body = $cond->sibling->first; # skip lineseq	    $cond = $self->deparse($cond, 1);	    $body = $self->deparse($body, 1);	    return "$body $name $cond";	}    } else {	$kid = $op->first;    }    for (; !null($kid); $kid = $kid->sibling) {	push @kids, $kid;    }    if ($cx > 0) { # inside an expression, (a do {} while for lineseq)	return "do {\n\t" . $self->lineseq($op, @kids) . "\n\b}";    } else {	my $lineseq = $self->lineseq($op, @kids);	return (length ($lineseq) ? "$lineseq;" : "");    }}sub pp_scope { scopeop(0, @_); }sub pp_lineseq { scopeop(0, @_); }sub pp_leave { scopeop(1, @_); }# This is a special case of scopeop and lineseq, for the case of the# main_root. The difference is that we print the output statements as# soon as we get them, for the sake of impatient users.sub deparse_root {    my $self = shift;    my($op) = @_;    local(@$self{qw'curstash warnings hints hinthash'})      = @$self{qw'curstash warnings hints hinthash'};    my @kids;    return if null $op->first; # Can happen, e.g., for Bytecode without -k    for (my $kid = $op->first->sibling; !null($kid); $kid = $kid->sibling) {	push @kids, $kid;    }    $self->walk_lineseq($op, \@kids,			sub { print $self->indent($_[0].';');			      print "\n" unless $_[1] == $#kids;			  });}sub walk_lineseq {    my ($self, $op, $kids, $callback) = @_;    my @kids = @$kids;    for (my $i = 0; $i < @kids; $i++) {	my $expr = "";	if (is_state $kids[$i]) {	    $expr = $self->deparse($kids[$i++], 0);	    if ($i > $#kids) {		$callback->($expr, $i);		last;	    }	}	if (is_for_loop($kids[$i])) {	    $callback->($expr . $self->for_loop($kids[$i], 0), $i++);	    next;	}	$expr .= $self->deparse($kids[$i], (@kids != 1)/2);	$expr =~ s/;\n?\z//;	$callback->($expr, $i);    }}# The BEGIN {} is used here because otherwise this code isn't executed# when you run B::Deparse on itself.my %globalnames;BEGIN { map($globalnames{$_}++, "SIG", "STDIN", "STDOUT", "STDERR", "INC",	    "ENV", "ARGV", "ARGVOUT", "_"); }sub gv_name {    my $self = shift;    my $gv = shift;Carp::confess() unless ref($gv) eq "B::GV";    my $stash = $gv->STASH->NAME;    my $name = $gv->SAFENAME;    if ($stash eq 'main' && $name =~ /^::/) {	$stash = '::';    }    elsif (($stash eq 'main' && $globalnames{$name})	or ($stash eq $self->{'curstash'} && !$globalnames{$name}	    && ($stash eq 'main' || $name !~ /::/))	or $name =~ /^[^A-Za-z_:]/)    {	$stash = "";    } else {	$stash = $stash . "::";    }    if ($name =~ /^(\^..|{)/) {        $name = "{$name}";       # ${^WARNING_BITS}, etc and ${    }    return $stash . $name;}# Return the name to use for a stash variable.# If a lexical with the same name is in scope, it may need to be# fully-qualified.sub stash_variable {    my ($self, $prefix, $name) = @_;    return "$prefix$name" if $name =~ /::/;    unless ($prefix eq '$' || $prefix eq '@' || #'	    $prefix eq '%' || $prefix eq '$#') {	return "$prefix$name";    }    my $v = ($prefix eq '$#' ? '@' : $prefix) . $name;    return $prefix .$self->{'curstash'}.'::'. $name if $self->lex_in_scope($v);    return "$prefix$name";}sub lex_in_scope {    my ($self, $name) = @_;    $self->populate_curcvlex() if !defined $self->{'curcvlex'};    return 0 if !defined($self->{'curcop'});    my $seq = $self->{'curcop'}->cop_seq;    return 0 if !exists $self->{'curcvlex'}{$name};    for my $a (@{$self->{'curcvlex'}{$name}}) {	my ($st, $en) = @$a;	return 1 if $seq > $st && $seq <= $en;    }    return 0;}sub populate_curcvlex {    my $self = shift;    for (my $cv = $self->{'curcv'}; class($cv) eq "CV"; $cv = $cv->OUTSIDE) {	my $padlist = $cv->PADLIST;	# an undef CV still in lexical chain	next if class($padlist) eq "SPECIAL";	my @padlist = $padlist->ARRAY;	my @ns = $padlist[0]->ARRAY;	for (my $i=0; $i<@ns; ++$i) {	    next if class($ns[$i]) eq "SPECIAL";	    next if $ns[$i]->FLAGS & SVpad_OUR;  # Skip "our" vars	    if (class($ns[$i]) eq "PV") {		# Probably that pesky lexical @_		next;	    }            my $name = $ns[$i]->PVX;	    my ($seq_st, $seq_en) =		($ns[$i]->FLAGS & SVf_FAKE)		    ? (0, 999999)		    : ($ns[$i]->COP_SEQ_RANGE_LOW, $ns[$i]->COP_SEQ_RANGE_HIGH);	    push @{$self->{'curcvlex'}{$name}}, [$seq_st, $seq_en];	}    }}sub find_scope_st { ((find_scope(@_))[0]); }sub find_scope_en { ((find_scope(@_))[1]); }# Recurses down the tree, looking for pad variable introductions and COPssub find_scope {    my ($self, $op, $scope_st, $scope_en) = @_;    carp("Undefined op in find_scope") if !defined $op;    return ($scope_st, $scope_en) unless $op->flags & OPf_KIDS;    my @queue = ($op);    while(my $op = shift @queue ) {	for (my $o=$op->first; $$o; $o=$o->sibling) {	    if ($o->name =~ /^pad.v$/ && $o->private & OPpLVAL_INTRO) {		my $s = int($self->padname_sv($o->targ)->COP_SEQ_RANGE_LOW);		my $e = $self->padname_sv($o->targ)->COP_SEQ_RANGE_HIGH;

⌨️ 快捷键说明

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