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

📄 simple.pm

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 PM
📖 第 1 页 / 共 2 页
字号:
package Filter::Simple;use Text::Balanced ':ALL';use vars qw{ $VERSION @EXPORT };$VERSION = '0.82';use Filter::Util::Call;use Carp;@EXPORT = qw( FILTER FILTER_ONLY );sub import {    if (@_>1) { shift; goto &FILTER }    else      { *{caller()."::$_"} = \&$_ foreach @EXPORT }}sub fail {    croak "FILTER_ONLY: ", @_;}my $exql = sub {    my @bits = extract_quotelike $_[0], qr//;    return unless $bits[0];    return \@bits;};my $ncws = qr/\s+/;my $comment = qr/(?<![\$\@%])#.*/;my $ws = qr/(?:$ncws|$comment)+/;my $id = qr/\b(?!([ysm]|q[rqxw]?|tr)\b)\w+/;my $EOP = qr/\n\n|\Z/;my $CUT = qr/\n=cut.*$EOP/;my $pod_or_DATA = qr/              ^=(?:head[1-4]|item) .*? $CUT            | ^=pod .*? $CUT            | ^=for .*? $EOP            | ^=begin \s* (\S+) .*? \n=end \s* \1 .*? $EOP            | ^__(DATA|END)__\r?\n.*            /smx;my %extractor_for = (    quotelike  => [ $ws,  \&extract_variable, $id, { MATCH  => \&extract_quotelike } ],    regex      => [ $ws,  $pod_or_DATA, $id, $exql           ],    string     => [ $ws,  $pod_or_DATA, $id, $exql           ],    code       => [ $ws, { DONT_MATCH => $pod_or_DATA },    		        \&extract_variable,                    $id, { DONT_MATCH => \&extract_quotelike }   ],    code_no_comments               => [ { DONT_MATCH => $comment },                    $ncws, { DONT_MATCH => $pod_or_DATA },    		        \&extract_variable,                    $id, { DONT_MATCH => \&extract_quotelike }   ],    executable => [ $ws, { DONT_MATCH => $pod_or_DATA }      ],    executable_no_comments               => [ { DONT_MATCH => $comment },                    $ncws, { DONT_MATCH => $pod_or_DATA }      ],    all        => [        { MATCH  => qr/(?s:.*)/         } ],);my %selector_for = (    all   => sub { my ($t)=@_; sub{ $_=$$_; $t->(@_); $_} },    executable=> sub { my ($t)=@_; sub{ref() ? $_=$$_ : $t->(@_); $_} },     quotelike => sub { my ($t)=@_; sub{ref() && do{$_=$$_; $t->(@_)}; $_} },    regex     => sub { my ($t)=@_;               sub{ref() or return $_;                   my ($ql,undef,$pre,$op,$ld,$pat) = @$_;                   return $_->[0] unless $op =~ /^(qr|m|s)/                         || !$op && ($ld eq '/' || $ld eq '?');                   $_ = $pat;                   $t->(@_);                   $ql =~ s/^(\s*\Q$op\E\s*\Q$ld\E)\Q$pat\E/$1$_/;                   return "$pre$ql";                  };            },    string     => sub { my ($t)=@_;               sub{ref() or return $_;                   local *args = \@_;                   my ($pre,$op,$ld1,$str1,$rd1,$ld2,$str2,$rd2,$flg) = @{$_}[2..10];                   return $_->[0] if $op =~ /^(qr|m)/                         || !$op && ($ld1 eq '/' || $ld1 eq '?');                   if (!$op || $op eq 'tr' || $op eq 'y') {                       local *_ = \$str1;                       $t->(@args);                   }                   if ($op =~ /^(tr|y|s)/) {                       local *_ = \$str2;                       $t->(@args);                   }                   my $result = "$pre$op$ld1$str1$rd1";                   $result .= $ld2 if $ld1 =~ m/[[({<]/; #])}>                   $result .= "$str2$rd2$flg";                   return $result;                  };              },);sub gen_std_filter_for {    my ($type, $transform) = @_;    return sub {        my $instr;        local @components;		for (extract_multiple($_,$extractor_for{$type})) {            if (ref())     { push @components, $_; $instr=0 }            elsif ($instr) { $components[-1] .= $_ }            else           { push @components, $_; $instr=1 }        }        if ($type =~ /^code/) {            my $count = 0;            local $placeholder = qr/\Q$;\E(\C{4})\Q$;\E/;            my $extractor =      qr/\Q$;\E(\C{4})\Q$;\E/;            $_ = join "",                  map { ref $_ ? $;.pack('N',$count++).$; : $_ }                      @components;            @components = grep { ref $_ } @components;            $transform->(@_);            s/$extractor/${$components[unpack('N',$1)]}/g;        }        else {            my $selector = $selector_for{$type}->($transform);            $_ = join "", map $selector->(@_), @components;        }    }};sub FILTER (&;$) {    my $caller = caller;    my ($filter, $terminator) = @_;    no warnings 'redefine';    *{"${caller}::import"} = gen_filter_import($caller,$filter,$terminator);    *{"${caller}::unimport"} = gen_filter_unimport($caller);}sub FILTER_ONLY {    my $caller = caller;    while (@_ > 1) {        my ($what, $how) = splice(@_, 0, 2);        fail "Unknown selector: $what"            unless exists $extractor_for{$what};        fail "Filter for $what is not a subroutine reference"            unless ref $how eq 'CODE';        push @transforms, gen_std_filter_for($what,$how);    }    my $terminator = shift;    my $multitransform = sub {        foreach my $transform ( @transforms ) {            $transform->(@_);        }    };    no warnings 'redefine';    *{"${caller}::import"} =        gen_filter_import($caller,$multitransform,$terminator);    *{"${caller}::unimport"} = gen_filter_unimport($caller);}my $ows    = qr/(?:[ \t]+|#[^\n]*)*/;sub gen_filter_import {    my ($class, $filter, $terminator) = @_;    my %terminator;    my $prev_import = *{$class."::import"}{CODE};    return sub {        my ($imported_class, @args) = @_;        my $def_terminator =            qr/^(?:\s*no\s+$imported_class\s*;$ows|__(?:END|DATA)__)\r?$/;        if (!defined $terminator) {            $terminator{terminator} = $def_terminator;        }        elsif (!ref $terminator || ref $terminator eq 'Regexp') {            $terminator{terminator} = $terminator;        }        elsif (ref $terminator ne 'HASH') {            croak "Terminator must be specified as scalar or hash ref"        }        elsif (!exists $terminator->{terminator}) {            $terminator{terminator} = $def_terminator;        }        filter_add(            sub {                my ($status, $lastline);                my $count = 0;                my $data = "";                while ($status = filter_read()) {                    return $status if $status < 0;                    if ($terminator{terminator} &&                        m/$terminator{terminator}/) {                        $lastline = $_;                        last;                    }                    $data .= $_;                    $count++;                    $_ = "";                }                return $count if not $count;                $_ = $data;                $filter->($imported_class, @args) unless $status < 0;                if (defined $lastline) {                    if (defined $terminator{becomes}) {                        $_ .= $terminator{becomes};                    }                    elsif ($lastline =~ $def_terminator) {                        $_ .= $lastline;                    }                }                return $count;            }        );        if ($prev_import) {            goto &$prev_import;        }        elsif ($class->isa('Exporter')) {            $class->export_to_level(1,@_);        }    }}sub gen_filter_unimport {    my ($class) = @_;    return sub {        filter_del();        goto &$prev_unimport if $prev_unimport;    }}1;__END__=head1 NAMEFilter::Simple - Simplified source filtering=head1 SYNOPSIS # in MyFilter.pm:     package MyFilter;     use Filter::Simple;          FILTER { ... };     # or just:     #     # use Filter::Simple sub { ... }; # in user's code:     use MyFilter;     # this code is filtered     no MyFilter;     # this code is not=head1 DESCRIPTION=head2 The ProblemSource filtering is an immensely powerful feature of recent versions of Perl.It allows one to extend the language itself (e.g. the Switch module), to simplify the language (e.g. Language::Pythonesque), or to completely recast thelanguage (e.g. Lingua::Romana::Perligata). Effectively, it allows one to usethe full power of Perl as its own, recursively applied, macro language.The excellent Filter::Util::Call module (by Paul Marquess) provides ausable Perl interface to source filtering, but it is often too powerfuland not nearly as simple as it could be.To use the module it is necessary to do the following:=over 4=item 1.Download, build, and install the Filter::Util::Call module.(If you have Perl 5.7.1 or later, this is already done for you.)=item 2.Set up a module that does a C<use Filter::Util::Call>.=item 3.Within that module, create an C<import> subroutine.=item 4.Within the C<import> subroutine do a call to C<filter_add>, passingit either a subroutine reference.=item 5.Within the subroutine reference, call C<filter_read> or C<filter_read_exact>to "prime" $_ with source code data from the source file that willC<use> your module. Check the status value returned to see if anysource code was actually read in.=item 6.Process the contents of $_ to change the source code in the desired manner.=item 7.Return the status value.=item 8.If the act of unimporting your module (via a C<no>) should cause sourcecode filtering to cease, create an C<unimport> subroutine, and have it callC<filter_del>. Make sure that the call to C<filter_read> orC<filter_read_exact> in step 5 will not accidentally read past theC<no>. Effectively this limits source code filters to line-by-lineoperation, unless the C<import> subroutine does some fancypre-pre-parsing of the source code it's filtering.=backFor example, here is a minimal source code filter in a module namedBANG.pm. It simply converts every occurrence of the sequence C<BANG\s+BANG>to the sequence C<die 'BANG' if $BANG> in any piece of code following aC<use BANG;> statement (until the next C<no BANG;> statement, if any):    package BANG;     use Filter::Util::Call ;    sub import {        filter_add( sub {        my $caller = caller;        my ($status, $no_seen, $data);        while ($status = filter_read()) {            if (/^\s*no\s+$caller\s*;\s*?$/) {                $no_seen=1;                last;            }            $data .= $_;            $_ = "";        }        $_ = $data;        s/BANG\s+BANG/die 'BANG' if \$BANG/g            unless $status < 0;        $_ .= "no $class;\n" if $no_seen;        return 1;        })    }    sub unimport {        filter_del();    }    1 ;This level of sophistication puts filtering out of the reach ofmany programmers.=head2 A SolutionThe Filter::Simple module provides a simplified interface toFilter::Util::Call; one that is sufficient for most common cases.Instead of the above process, with Filter::Simple the task of setting upa source code filter is reduced to:=over 4=item 1.Download and install the Filter::Simple module.(If you have Perl 5.7.1 or later, this is already done for you.)=item 2.Set up a module that does a C<use Filter::Simple> and thencalls C<FILTER { ... }>.=item 3.Within the anonymous subroutine or block that is passed toC<FILTER>, process the contents of $_ to change the source code inthe desired manner.=back

⌨️ 快捷键说明

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