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

📄 deparse.pm

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 PM
📖 第 1 页 / 共 5 页
字号:
# B::Deparse.pm# Copyright (c) 1998-2000, 2002, 2003, 2004, 2005, 2006 Stephen McCamant.# All rights reserved.# This module is free software; you can redistribute and/or modify# it under the same terms as Perl itself.# This is based on the module of the same name by Malcolm Beattie,# but essentially none of his code remains.package B::Deparse;use Carp;use B qw(class main_root main_start main_cv svref_2object opnumber perlstring	 OPf_WANT OPf_WANT_VOID OPf_WANT_SCALAR OPf_WANT_LIST	 OPf_KIDS OPf_REF OPf_STACKED OPf_SPECIAL OPf_MOD OPpPAD_STATE	 OPpLVAL_INTRO OPpOUR_INTRO OPpENTERSUB_AMPER OPpSLICE OPpCONST_BARE	 OPpTRANS_SQUASH OPpTRANS_DELETE OPpTRANS_COMPLEMENT OPpTARGET_MY	 OPpCONST_ARYBASE OPpEXISTS_SUB OPpSORT_NUMERIC OPpSORT_INTEGER	 OPpSORT_REVERSE OPpSORT_INPLACE OPpSORT_DESCEND OPpITER_REVERSED	 SVf_IOK SVf_NOK SVf_ROK SVf_POK SVpad_OUR SVf_FAKE SVs_RMG SVs_SMG         CVf_METHOD CVf_LOCKED CVf_LVALUE	 PMf_KEEP PMf_GLOBAL PMf_CONTINUE PMf_EVAL PMf_ONCE	 PMf_MULTILINE PMf_SINGLELINE PMf_FOLD PMf_EXTENDED),	 ($] < 5.009 ? 'PMf_SKIPWHITE' : 'RXf_SKIPWHITE');$VERSION = 0.83;use strict;use vars qw/$AUTOLOAD/;use warnings ();# Changes between 0.50 and 0.51:# - fixed nulled leave with live enter in sort { }# - fixed reference constants (\"str")# - handle empty programs gracefully# - handle infinte loops (for (;;) {}, while (1) {})# - differentiate between `for my $x ...' and `my $x; for $x ...'# - various minor cleanups# - moved globals into an object# - added `-u', like B::C# - package declarations using cop_stash# - subs, formats and code sorted by cop_seq# Changes between 0.51 and 0.52:# - added pp_threadsv (special variables under USE_5005THREADS)# - added documentation# Changes between 0.52 and 0.53:# - many changes adding precedence contexts and associativity# - added `-p' and `-s' output style options# - various other minor fixes# Changes between 0.53 and 0.54:# - added support for new `for (1..100)' optimization,#   thanks to Gisle Aas# Changes between 0.54 and 0.55:# - added support for new qr// construct# - added support for new pp_regcreset OP# Changes between 0.55 and 0.56:# - tested on base/*.t, cmd/*.t, comp/*.t, io/*.t# - fixed $# on non-lexicals broken in last big rewrite# - added temporary fix for change in opcode of OP_STRINGIFY# - fixed problem in 0.54's for() patch in `for (@ary)'# - fixed precedence in conditional of ?:# - tweaked list paren elimination in `my($x) = @_'# - made continue-block detection trickier wrt. null ops# - fixed various prototype problems in pp_entersub# - added support for sub prototypes that never get GVs# - added unquoting for special filehandle first arg in truncate# - print doubled rv2gv (a bug) as `*{*GV}' instead of illegal `**GV'# - added semicolons at the ends of blocks# - added -l `#line' declaration option -- fixes cmd/subval.t 27,28# Changes between 0.56 and 0.561:# - fixed multiply-declared my var in pp_truncate (thanks to Sarathy)# - used new B.pm symbolic constants (done by Nick Ing-Simmons)# Changes between 0.561 and 0.57:# - stylistic changes to symbolic constant stuff# - handled scope in s///e replacement code# - added unquote option for expanding "" into concats, etc.# - split method and proto parts of pp_entersub into separate functions# - various minor cleanups# Changes after 0.57:# - added parens in \&foo (patch by Albert Dvornik)# Changes between 0.57 and 0.58:# - fixed `0' statements that weren't being printed# - added methods for use from other programs#   (based on patches from James Duncan and Hugo van der Sanden)# - added -si and -sT to control indenting (also based on a patch from Hugo)# - added -sv to print something else instead of '???'# - preliminary version of utf8 tr/// handling# Changes after 0.58:# - uses of $op->ppaddr changed to new $op->name (done by Sarathy)# - added support for Hugo's new OP_SETSTATE (like nextstate)# Changes between 0.58 and 0.59# - added support for Chip's OP_METHOD_NAMED# - added support for Ilya's OPpTARGET_MY optimization# - elided arrows before `()' subscripts when possible# Changes between 0.59 and 0.60# - support for method attribues was added# - some warnings fixed# - separate recognition of constant subs# - rewrote continue block handling, now recoginizing for loops# - added more control of expanding control structures# Changes between 0.60 and 0.61 (mostly by Robin Houston)# - many bug-fixes# - support for pragmas and 'use'# - support for the little-used $[ variable# - support for __DATA__ sections# - UTF8 support# - BEGIN, CHECK, INIT and END blocks# - scoping of subroutine declarations fixed# - compile-time output from the input program can be suppressed, so that the#   output is just the deparsed code. (a change to O.pm in fact)# - our() declarations# - *all* the known bugs are now listed in the BUGS section# - comprehensive test mechanism (TEST -deparse)# Changes between 0.62 and 0.63 (mostly by Rafael Garcia-Suarez)# - bug-fixes# - new switch -P# - support for command-line switches (-l, -0, etc.)# Changes between 0.63 and 0.64# - support for //, CHECK blocks, and assertions# - improved handling of foreach loops and lexicals# - option to use Data::Dumper for constants# - more bug fixes# - discovered lots more bugs not yet fixed## ...## Changes between 0.72 and 0.73# - support new switch constructs# Todo:#  (See also BUGS section at the end of this file)## - finish tr/// changes# - add option for even more parens (generalize \&foo change)# - left/right context# - copy comments (look at real text with $^P?)# - avoid semis in one-statement blocks# - associativity of &&=, ||=, ?:# - ',' => '=>' (auto-unquote?)# - break long lines ("\r" as discretionary break?)# - configurable syntax highlighting: ANSI color, HTML, TeX, etc.# - more style options: brace style, hex vs. octal, quotes, ...# - print big ints as hex/octal instead of decimal (heuristic?)# - handle `my $x if 0'?# - version using op_next instead of op_first/sibling?# - avoid string copies (pass arrays, one big join?)# - here-docs?# Current test.deparse failures# comp/hints 6 - location of BEGIN blocks wrt. block openings# run/switchI 1 - missing -I switches entirely#    perl -Ifoo -e 'print @INC'# op/caller 2 - warning mask propagates backwards before warnings::register#    'use warnings; BEGIN {${^WARNING_BITS} eq "U"x12;} use warnings::register'# op/getpid 2 - can't assign to shared my() declaration (threads only)#    'my $x : shared = 5'# op/override 7 - parens on overriden require change v-string interpretation#    'BEGIN{*CORE::GLOBAL::require=sub {}} require v5.6'#    c.f. 'BEGIN { *f = sub {0} }; f 2'# op/pat 774 - losing Unicode-ness of Latin1-only strings#    'use charnames ":short"; $x="\N{latin:a with acute}"'# op/recurse 12 - missing parens on recursive call makes it look like method#    'sub f { f($x) }'# op/subst 90 - inconsistent handling of utf8 under "use utf8"# op/taint 29 - "use re 'taint'" deparsed in the wrong place wrt. block open# op/tiehandle compile - "use strict" deparsed in the wrong place# uni/tr_ several# ext/B/t/xref 11 - line numbers when we add newlines to one-line subs# ext/Data/Dumper/t/dumper compile# ext/DB_file/several# ext/Encode/several# ext/Ernno/Errno warnings# ext/IO/lib/IO/t/io_sel 23# ext/PerlIO/t/encoding compile# ext/POSIX/t/posix 6# ext/Socket/Socket 8# ext/Storable/t/croak compile# lib/Attribute/Handlers/t/multi compile# lib/bignum/ several# lib/charnames 35# lib/constant 32# lib/English 40# lib/ExtUtils/t/bytes 4# lib/File/DosGlob compile# lib/Filter/Simple/t/data 1# lib/Math/BigInt/t/constant 1# lib/Net/t/config Deparse-warning# lib/overload compile# lib/Switch/ several# lib/Symbol 4# lib/Test/Simple several# lib/Term/Complete# lib/Tie/File/t/29_downcopy 5# lib/vars 22# Object fields (were globals):## avoid_local:# (local($a), local($b)) and local($a, $b) have the same internal# representation but the short form looks better. We notice we can# use a large-scale local when checking the list, but need to prevent# individual locals too. This hash holds the addresses of OPs that# have already had their local-ness accounted for. The same thing# is done with my().## curcv:# CV for current sub (or main program) being deparsed## curcvlex:# Cached hash of lexical variables for curcv: keys are names,# each value is an array of pairs, indicating the cop_seq of scopes# in which a var of that name is valid.## curcop:# COP for statement being deparsed## curstash:# name of the current package for deparsed code## subs_todo:# array of [cop_seq, CV, is_format?] for subs and formats we still# want to deparse## protos_todo:# as above, but [name, prototype] for subs that never got a GV## subs_done, forms_done:# keys are addresses of GVs for subs and formats we've already# deparsed (or at least put into subs_todo)## subs_declared# keys are names of subs for which we've printed declarations.# That means we can omit parentheses from the arguments.## subs_deparsed# Keeps track of fully qualified names of all deparsed subs.## parens: -p# linenums: -l# unquote: -q# cuddle: ` ' or `\n', depending on -sC# indent_size: -si# use_tabs: -sT# ex_const: -sv# A little explanation of how precedence contexts and associativity# work:## deparse() calls each per-op subroutine with an argument $cx (short# for context, but not the same as the cx* in the perl core), which is# a number describing the op's parents in terms of precedence, whether# they're inside an expression or at statement level, etc.  (see# chart below). When ops with children call deparse on them, they pass# along their precedence. Fractional values are used to implement# associativity (`($x + $y) + $z' => `$x + $y + $y') and related# parentheses hacks. The major disadvantage of this scheme is that# it doesn't know about right sides and left sides, so say if you# assign a listop to a variable, it can't tell it's allowed to leave# the parens off the listop.# Precedences:# 26             [TODO] inside interpolation context ("")# 25 left        terms and list operators (leftward)# 24 left        -># 23 nonassoc    ++ --# 22 right       **# 21 right       ! ~ \ and unary + and -# 20 left        =~ !~# 19 left        * / % x# 18 left        + - .# 17 left        << >># 16 nonassoc    named unary operators# 15 nonassoc    < > <= >= lt gt le ge# 14 nonassoc    == != <=> eq ne cmp# 13 left        &# 12 left        | ^# 11 left        &&# 10 left        ||#  9 nonassoc    ..  ...#  8 right       ?:#  7 right       = += -= *= etc.#  6 left        , =>#  5 nonassoc    list operators (rightward)#  4 right       not#  3 left        and#  2 left        or xor#  1             statement modifiers#  0.5           statements, but still print scopes as do { ... }#  0             statement level# Nonprinting characters with special meaning:# \cS - steal parens (see maybe_parens_unop)# \n - newline and indent# \t - increase indent# \b - decrease indent (`outdent')# \f - flush left (no indent)# \cK - kill following semicolon, if anysub null {    my $op = shift;    return class($op) eq "NULL";}sub todo {    my $self = shift;    my($cv, $is_form) = @_;    return unless ($cv->FILE eq $0 || exists $self->{files}{$cv->FILE});    my $seq;    if ($cv->OUTSIDE_SEQ) {	$seq = $cv->OUTSIDE_SEQ;    } elsif (!null($cv->START) and is_state($cv->START)) {	$seq = $cv->START->cop_seq;    } else {	$seq = 0;    }    push @{$self->{'subs_todo'}}, [$seq, $cv, $is_form];    unless ($is_form || class($cv->STASH) eq 'SPECIAL') {	$self->{'subs_deparsed'}{$cv->STASH->NAME."::".$cv->GV->NAME} = 1;    }}sub next_todo {    my $self = shift;    my $ent = shift @{$self->{'subs_todo'}};    my $cv = $ent->[1];    my $gv = $cv->GV;    my $name = $self->gv_name($gv);    if ($ent->[2]) {	return "format $name =\n"	    . $self->deparse_format($ent->[1]). "\n";    } else {	$self->{'subs_declared'}{$name} = 1;	if ($name eq "BEGIN") {	    my $use_dec = $self->begin_is_use($cv);	    if (defined ($use_dec) and $self->{'expand'} < 5) {		return () if 0 == length($use_dec);		return $use_dec;	    }	}	my $l = '';	if ($self->{'linenums'}) {	    my $line = $gv->LINE;	    my $file = $gv->FILE;	    $l = "\n\f#line $line \"$file\"\n";	}	my $p = '';	if (class($cv->STASH) ne "SPECIAL") {	    my $stash = $cv->STASH->NAME;	    if ($stash ne $self->{'curstash'}) {		$p = "package $stash;\n";		$name = "$self->{'curstash'}::$name" unless $name =~ /::/;		$self->{'curstash'} = $stash;	    }	    $name =~ s/^\Q$stash\E::(?!\z|.*::)//;	}        return "${p}${l}sub $name " . $self->deparse_sub($cv);    }}# Return a "use" declaration for this BEGIN block, if appropriatesub begin_is_use {    my ($self, $cv) = @_;    my $root = $cv->ROOT;    local @$self{qw'curcv curcvlex'} = ($cv);#require B::Debug;#B::walkoptree($cv->ROOT, "debug");    my $lineseq = $root->first;    return if $lineseq->name ne "lineseq";    my $req_op = $lineseq->first->sibling;    return if $req_op->name ne "require";    my $module;    if ($req_op->first->private & OPpCONST_BARE) {	# Actually it should always be a bareword	$module = $self->const_sv($req_op->first)->PV;	$module =~ s[/][::]g;	$module =~ s/.pm$//;    }    else {	$module = $self->const($self->const_sv($req_op->first), 6);    }    my $version;    my $version_op = $req_op->sibling;    return if class($version_op) eq "NULL";    if ($version_op->name eq "lineseq") {	# We have a version parameter; skip nextstate & pushmark	my $constop = $version_op->first->next->next;	return unless $self->const_sv($constop)->PV eq $module;	$constop = $constop->sibling;	$version = $self->const_sv($constop);	if (class($version) eq "IV") {	    $version = $version->int_value;	} elsif (class($version) eq "NV") {	    $version = $version->NV;	} elsif (class($version) ne "PVMG") {	    # Includes PVIV and PVNV	    $version = $version->PV;	} else {	    # version specified as a v-string	    $version = 'v'.join '.', map ord, split //, $version->PV;	}	$constop = $constop->sibling;	return if $constop->name ne "method_named";	return if $self->const_sv($constop)->PV ne "VERSION";    }    $lineseq = $version_op->sibling;    return if $lineseq->name ne "lineseq";    my $entersub = $lineseq->first->sibling;    if ($entersub->name eq "stub") {	return "use $module $version ();\n" if defined $version;	return "use $module ();\n";    }    return if $entersub->name ne "entersub";    # See if there are import arguments    my $args = '';    my $svop = $entersub->first->sibling; # Skip over pushmark    return unless $self->const_sv($svop)->PV eq $module;    # Pull out the arguments    for ($svop=$svop->sibling; $svop->name ne "method_named";		$svop = $svop->sibling) {	$args .= ", " if length($args);	$args .= $self->deparse($svop, 6);    }    my $use = 'use';    my $method_named = $svop;    return if $method_named->name ne "method_named";    my $method_name = $self->const_sv($method_named)->PV;    if ($method_name eq "unimport") {	$use = 'no';    }    # Certain pragmas are dealt with using hint bits,    # so we ignore them here

⌨️ 快捷键说明

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