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

📄 concise.pm

📁 source of perl for linux application,
💻 PM
📖 第 1 页 / 共 4 页
字号:
package B::Concise;# Copyright (C) 2000-2003 Stephen McCamant. All rights reserved.# This program is free software; you can redistribute and/or modify it# under the same terms as Perl itself.# Note: we need to keep track of how many use declarations/BEGIN# blocks this module uses, so we can avoid printing them when user# asks for the BEGIN blocks in her program. Update the comments and# the count in concise_specials if you add or delete one. The# -MO=Concise counts as use #1.use strict; # use #2use warnings; # uses #3 and #4, since warnings uses Carpuse Exporter (); # use #5our $VERSION   = "0.74";our @ISA       = qw(Exporter);our @EXPORT_OK = qw( set_style set_style_standard add_callback		     concise_subref concise_cv concise_main		     add_style walk_output compile reset_sequence );our %EXPORT_TAGS =    ( io	=> [qw( walk_output compile reset_sequence )],      style	=> [qw( add_style set_style_standard )],      cb	=> [qw( add_callback )],      mech	=> [qw( concise_subref concise_cv concise_main )],  );# use #6use B qw(class ppname main_start main_root main_cv cstring svref_2object	 SVf_IOK SVf_NOK SVf_POK SVf_IVisUV SVf_FAKE OPf_KIDS OPf_SPECIAL	 CVf_ANON PAD_FAKELEX_ANON PAD_FAKELEX_MULTI);my %style =  ("terse" =>   ["(?(#label =>\n)?)(*(    )*)#class (#addr) #name (?([#targ])?) "    . "#svclass~(?((#svaddr))?)~#svval~(?(label \"#coplabel\")?)\n",    "(*(    )*)goto #class (#addr)\n",    "#class pp_#name"],   "concise" =>   ["#hyphseq2 (*(   (x( ;)x))*)<#classsym> #exname#arg(?([#targarglife])?)"    . "~#flags(?(/#private)?)(?(:#hints)?)(x(;~->#next)x)\n"    , "  (*(    )*)     goto #seq\n",    "(?(<#seq>)?)#exname#arg(?([#targarglife])?)"],   "linenoise" =>   ["(x(;(*( )*))x)#noise#arg(?([#targarg])?)(x( ;\n)x)",    "gt_#seq ",    "(?(#seq)?)#noise#arg(?([#targarg])?)"],   "debug" =>   ["#class (#addr)\n\top_next\t\t#nextaddr\n\top_sibling\t#sibaddr\n\t"    . "op_ppaddr\tPL_ppaddr[OP_#NAME]\n\top_type\t\t#typenum\n" .    ($] > 5.009 ? '' : "\top_seq\t\t#seqnum\n")    . "\top_flags\t#flagval\n\top_private\t#privval\t#hintsval\n"    . "(?(\top_first\t#firstaddr\n)?)(?(\top_last\t\t#lastaddr\n)?)"    . "(?(\top_sv\t\t#svaddr\n)?)",    "    GOTO #addr\n",    "#addr"],   "env" => [$ENV{B_CONCISE_FORMAT}, $ENV{B_CONCISE_GOTO_FORMAT},	     $ENV{B_CONCISE_TREE_FORMAT}],  );# Renderings, ie how Concise prints, is controlled by these vars# primary:our $stylename;		# selects current style from %stylemy $order = "basic";	# how optree is walked & printed: basic, exec, tree# rendering mechanics:# these 'formats' are the line-rendering templates# they're updated from %style when $stylename changesmy ($format, $gotofmt, $treefmt);# lesser players:my $base = 36;		# how <sequence#> is displayedmy $big_endian = 1;	# more <sequence#> displaymy $tree_style = 0;	# tree-order detailsmy $banner = 1;		# print banner before optree is traversedmy $do_main = 0;	# force printing of main routinemy $show_src;		# show source code# another factor: can affect all styles!our @callbacks;		# allow external managementset_style_standard("concise");my $curcv;my $cop_seq_base;sub set_style {    ($format, $gotofmt, $treefmt) = @_;    #warn "set_style: deprecated, use set_style_standard instead\n"; # someday    die "expecting 3 style-format args\n" unless @_ == 3;}sub add_style {    my ($newstyle,@args) = @_;    die "style '$newstyle' already exists, choose a new name\n"	if exists $style{$newstyle};    die "expecting 3 style-format args\n" unless @args == 3;    $style{$newstyle} = [@args];    $stylename = $newstyle; # update rendering state}sub set_style_standard {    ($stylename) = @_; # update rendering state    die "err: style '$stylename' unknown\n" unless exists $style{$stylename};    set_style(@{$style{$stylename}});}sub add_callback {    push @callbacks, @_;}# output handle, used with all Concise-output printingour $walkHandle;	# public for your convenienceBEGIN { $walkHandle = \*STDOUT }sub walk_output { # updates $walkHandle    my $handle = shift;    return $walkHandle unless $handle; # allow use as accessor    if (ref $handle eq 'SCALAR') {	require Config;	die "no perlio in this build, can't call walk_output (\\\$scalar)\n"	    unless $Config::Config{useperlio};	# in 5.8+, open(FILEHANDLE,MODE,REFERENCE) writes to string	open my $tmp, '>', $handle;	# but cant re-set existing STDOUT	$walkHandle = $tmp;		# so use my $tmp as intermediate var	return $walkHandle;    }    my $iotype = ref $handle;    die "expecting argument/object that can print\n"	unless $iotype eq 'GLOB' or $iotype and $handle->can('print');    $walkHandle = $handle;}sub concise_subref {    my($order, $coderef, $name) = @_;    my $codeobj = svref_2object($coderef);    return concise_stashref(@_)	unless ref $codeobj eq 'B::CV';    concise_cv_obj($order, $codeobj, $name);}sub concise_stashref {    my($order, $h) = @_;    local *s;    foreach my $k (sort keys %$h) {	next unless defined $h->{$k};	*s = $h->{$k};	my $coderef = *s{CODE} or next;	reset_sequence();	print "FUNC: ", *s, "\n";	my $codeobj = svref_2object($coderef);	next unless ref $codeobj eq 'B::CV';	eval { concise_cv_obj($order, $codeobj, $k) };	warn "err $@ on $codeobj" if $@;    }}# This should have been called concise_subref, but it was exported# under this name in versions before 0.56*concise_cv = \&concise_subref;sub concise_cv_obj {    my ($order, $cv, $name) = @_;    # name is either a string, or a CODE ref (copy of $cv arg??)    $curcv = $cv;    if (ref($cv->XSUBANY) =~ /B::(\w+)/) {	print $walkHandle "$name is a constant sub, optimized to a $1\n";	return;    }    if ($cv->XSUB) {	print $walkHandle "$name is XS code\n";	return;    }    if (class($cv->START) eq "NULL") {	no strict 'refs';	if (ref $name eq 'CODE') {	    print $walkHandle "coderef $name has no START\n";	}	elsif (exists &$name) {	    print $walkHandle "$name exists in stash, but has no START\n";	}	else {	    print $walkHandle "$name not in symbol table\n";	}	return;    }    sequence($cv->START);    if ($order eq "exec") {	walk_exec($cv->START);    }    elsif ($order eq "basic") {	# walk_topdown($cv->ROOT, sub { $_[0]->concise($_[1]) }, 0);	my $root = $cv->ROOT;	unless (ref $root eq 'B::NULL') {	    walk_topdown($root, sub { $_[0]->concise($_[1]) }, 0);	} else {	    print $walkHandle "B::NULL encountered doing ROOT on $cv. avoiding disaster\n";	}    } else {	print $walkHandle tree($cv->ROOT, 0);    }}sub concise_main {    my($order) = @_;    sequence(main_start);    $curcv = main_cv;    if ($order eq "exec") {	return if class(main_start) eq "NULL";	walk_exec(main_start);    } elsif ($order eq "tree") {	return if class(main_root) eq "NULL";	print $walkHandle tree(main_root, 0);    } elsif ($order eq "basic") {	return if class(main_root) eq "NULL";	walk_topdown(main_root,		     sub { $_[0]->concise($_[1]) }, 0);    }}sub concise_specials {    my($name, $order, @cv_s) = @_;    my $i = 1;    if ($name eq "BEGIN") {	splice(@cv_s, 0, 8); # skip 7 BEGIN blocks in this file. NOW 8 ??    } elsif ($name eq "CHECK") {	pop @cv_s; # skip the CHECK block that calls us    }    for my $cv (@cv_s) {	print $walkHandle "$name $i:\n";	$i++;	concise_cv_obj($order, $cv, $name);    }}my $start_sym = "\e(0"; # "\cN" sometimes also worksmy $end_sym   = "\e(B"; # "\cO" respectivelymy @tree_decorations =  (["  ", "--", "+-", "|-", "| ", "`-", "-", 1],   [" ", "-", "+", "+", "|", "`", "", 0],   ["  ", map("$start_sym$_$end_sym", "qq", "wq", "tq", "x ", "mq", "q"), 1],   [" ", map("$start_sym$_$end_sym", "q", "w", "t", "x", "m"), "", 0],  );my @render_packs; # collect -stash=<packages>sub compileOpts {    # set rendering state from options and args    my (@options,@args);    if (@_) {	@options = grep(/^-/, @_);	@args = grep(!/^-/, @_);    }    for my $o (@options) {	# mode/order	if ($o eq "-basic") {	    $order = "basic";	} elsif ($o eq "-exec") {	    $order = "exec";	} elsif ($o eq "-tree") {	    $order = "tree";	}	# tree-specific	elsif ($o eq "-compact") {	    $tree_style |= 1;	} elsif ($o eq "-loose") {	    $tree_style &= ~1;	} elsif ($o eq "-vt") {	    $tree_style |= 2;	} elsif ($o eq "-ascii") {	    $tree_style &= ~2;	}	# sequence numbering	elsif ($o =~ /^-base(\d+)$/) {	    $base = $1;	} elsif ($o eq "-bigendian") {	    $big_endian = 1;	} elsif ($o eq "-littleendian") {	    $big_endian = 0;	}	# miscellaneous, presentation	elsif ($o eq "-nobanner") {	    $banner = 0;	} elsif ($o eq "-banner") {	    $banner = 1;	}	elsif ($o eq "-main") {	    $do_main = 1;	} elsif ($o eq "-nomain") {	    $do_main = 0;	} elsif ($o eq "-src") {	    $show_src = 1;	}	elsif ($o =~ /^-stash=(.*)/) {	    my $pkg = $1;	    no strict 'refs';	    eval "require $pkg" unless defined %{$pkg.'::'};	    push @render_packs, $pkg;	}	# line-style options	elsif (exists $style{substr($o, 1)}) {	    $stylename = substr($o, 1);	    set_style_standard($stylename);	} else {	    warn "Option $o unrecognized";	}    }    return (@args);}sub compile {    my (@args) = compileOpts(@_);    return sub {	my @newargs = compileOpts(@_); # accept new rendering options	warn "disregarding non-options: @newargs\n" if @newargs;	for my $objname (@args) {	    next unless $objname; # skip null args to avoid noisy responses	    if ($objname eq "BEGIN") {		concise_specials("BEGIN", $order,				 B::begin_av->isa("B::AV") ?				 B::begin_av->ARRAY : ());	    } elsif ($objname eq "INIT") {		concise_specials("INIT", $order,				 B::init_av->isa("B::AV") ?				 B::init_av->ARRAY : ());	    } elsif ($objname eq "CHECK") {		concise_specials("CHECK", $order,				 B::check_av->isa("B::AV") ?				 B::check_av->ARRAY : ());	    } elsif ($objname eq "UNITCHECK") {		concise_specials("UNITCHECK", $order,				 B::unitcheck_av->isa("B::AV") ?				 B::unitcheck_av->ARRAY : ());	    } elsif ($objname eq "END") {		concise_specials("END", $order,				 B::end_av->isa("B::AV") ?				 B::end_av->ARRAY : ());	    }	    else {		# convert function names to subrefs		my $objref;		if (ref $objname) {		    print $walkHandle "B::Concise::compile($objname)\n"			if $banner;		    $objref = $objname;		} else {		    $objname = "main::" . $objname unless $objname =~ /::/;		    print $walkHandle "$objname:\n";		    no strict 'refs';		    unless (exists &$objname) {			print $walkHandle "err: unknown function ($objname)\n";			return;		    }		    $objref = \&$objname;		}		concise_subref($order, $objref, $objname);	    }	}	for my $pkg (@render_packs) {	    no strict 'refs';	    concise_stashref($order, \%{$pkg.'::'});	}	if (!@args or $do_main or @render_packs) {	    print $walkHandle "main program:\n" if $do_main;	    concise_main($order);	}	return @args;	# something    }}my %labels;my $lastnext;	# remembers op-chain, used to insert gotosmy %opclass = ('OP' => "0", 'UNOP' => "1", 'BINOP' => "2", 'LOGOP' => "|",	       'LISTOP' => "@", 'PMOP' => "/", 'SVOP' => "\$", 'GVOP' => "*",	       'PVOP' => '"', 'LOOP' => "{", 'COP' => ";", 'PADOP' => "#");no warnings 'qw'; # "Possible attempt to put comments..."; use #7my @linenoise =  qw'#  () sc (  @? 1  $* gv *{ m$ m@ m% m? p/ *$ $  $# & a& pt \\ s\\ rf bl     `  *? <> ?? ?/ r/ c/ // qr s/ /c y/ =  @= C  sC Cp sp df un BM po +1 +I     -1 -I 1+ I+ 1- I- ** *  i* /  i/ %$ i% x  +  i+ -  i- .  "  << >> <  i<     >  i> <= i, >= i. == i= != i! <? i? s< s> s, s. s= s! s? b& b^ b| -0 -i     !  ~  a2 si cs rd sr e^ lg sq in %x %o ab le ss ve ix ri sf FL od ch cy     uf lf uc lc qm @  [f [  @[ eh vl ky dl ex %  ${ @{ uk pk st jn )  )[ a@     a% sl +] -] [- [+ so rv GS GW MS MW .. f. .f && || ^^ ?: &= |= -> s{ s}     v} ca wa di rs ;; ;  ;d }{ {  }  {} f{ it {l l} rt }l }n }r dm }g }e ^o     ^c ^| ^# um bm t~ u~ ~d DB db ^s se ^g ^r {w }w pf pr ^O ^K ^R ^W ^d ^v     ^e ^t ^k t. fc ic fl .s .p .b .c .l .a .h g1 s1 g2 s2 ?. l? -R -W -X -r     -w -x -e -o -O -z -s -M -A -C -S -c -b -f -d -p -l -u -g -k -t -T -B cd     co cr u. cm ut r. l@ s@ r@ mD uD oD rD tD sD wD cD f$ w$ p$ sh e$ k$ g3     g4 s4 g5 s5 T@ C@ L@ G@ A@ S@ Hg Hc Hr Hw Mg Mc Ms Mr Sg Sc So rq do {e     e} {t t} g6 G6 6e g7 G7 7e g8 G8 8e g9 G9 9e 6s 7s 8s 9s 6E 7E 8E 9E Pn     Pu GP SP EP Gn Gg GG SG EG g0 c$ lk t$ ;s n> // /= CO';my $chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";sub op_flags { # common flags (see BASOP.op_flags in op.h)    my($x) = @_;    my(@v);    push @v, "v" if ($x & 3) == 1;    push @v, "s" if ($x & 3) == 2;    push @v, "l" if ($x & 3) == 3;    push @v, "K" if $x & 4;    push @v, "P" if $x & 8;    push @v, "R" if $x & 16;    push @v, "M" if $x & 32;    push @v, "S" if $x & 64;    push @v, "*" if $x & 128;    return join("", @v);}sub base_n {    my $x = shift;    return "-" . base_n(-$x) if $x < 0;    my $str = "";    do { $str .= substr($chars, $x % $base, 1) } while $x = int($x / $base);    $str = reverse $str if $big_endian;    return $str;}my %sequence_num;my $seq_max = 1;sub reset_sequence {    # reset the sequence    %sequence_num = ();    $seq_max = 1;    $lastnext = 0;}sub seq {    my($op) = @_;    return "-" if not exists $sequence_num{$$op};    return base_n($sequence_num{$$op});}sub walk_topdown {    my($op, $sub, $level) = @_;    $sub->($op, $level);    if ($op->flags & OPf_KIDS) {	for (my $kid = $op->first; $$kid; $kid = $kid->sibling) {	    walk_topdown($kid, $sub, $level + 1);	}    }    elsif (class($op) eq "PMOP") {	my $maybe_root = $op->pmreplroot;

⌨️ 快捷键说明

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