⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.144
Server IP:
157.245.143.252
Server:
Linux www 6.11.0-9-generic #9-Ubuntu SMP PREEMPT_DYNAMIC Mon Oct 14 13:19:59 UTC 2024 x86_64
Server Software:
nginx/1.26.0
PHP Version:
8.3.11
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
lib
/
x86_64-linux-gnu
/
perl
/
5.38.2
/
Filter
/
Util
/
View File Name :
Call.pm
# Call.pm # # Copyright (c) 1995-2011 Paul Marquess. All rights reserved. # Copyright (c) 2011-2014, 2018-2022 Reini Urban. All rights reserved. # Copyright (c) 2014-2017 cPanel Inc. All rights reserved. # # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. package Filter::Util::Call ; require 5.006 ; # our require Exporter; use XSLoader (); use strict; use warnings; our @ISA = qw(Exporter); our @EXPORT = qw( filter_add filter_del filter_read filter_read_exact) ; our $VERSION = "1.64" ; our $XS_VERSION = $VERSION; $VERSION = eval $VERSION; sub filter_read_exact($) { my ($size) = @_ ; my ($left) = $size ; my ($status) ; unless ( $size > 0 ) { require Carp; Carp::croak("filter_read_exact: size parameter must be > 0"); } # try to read a block which is exactly $size bytes long while ($left and ($status = filter_read($left)) > 0) { $left = $size - length $_ ; } # EOF with pending data is a special case return 1 if $status == 0 and length $_ ; return $status ; } sub filter_add($) { my($obj) = @_ ; # Did we get a code reference? my $coderef = (ref $obj eq 'CODE'); # If the parameter isn't already a reference, make it one. if (!$coderef and (!ref($obj) or ref($obj) =~ /^ARRAY|HASH$/)) { $obj = bless (\$obj, (caller)[0]); } # finish off the installation of the filter in C. Filter::Util::Call::real_import($obj, (caller)[0], $coderef) ; } XSLoader::load('Filter::Util::Call'); 1; __END__ =head1 NAME Filter::Util::Call - Perl Source Filter Utility Module =head1 SYNOPSIS use Filter::Util::Call ; =head1 DESCRIPTION This module provides you with the framework to write I
in Perl. An alternate interface to Filter::Util::Call is now available. See L
for more details. A I
is implemented as a Perl module. The structure of the module can take one of two broadly similar formats. To distinguish between them, the first will be referred to as I
and the second as I
. Here is a skeleton for the I
: package MyFilter ; use Filter::Util::Call ; sub import { my($type, @arguments) = @_ ; filter_add([]) ; } sub filter { my($self) = @_ ; my($status) ; $status = filter_read() ; $status ; } 1 ; and this is the equivalent skeleton for the I
: package MyFilter ; use Filter::Util::Call ; sub import { my($type, @arguments) = @_ ; filter_add( sub { my($status) ; $status = filter_read() ; $status ; } ) } 1 ; To make use of either of the two filter modules above, place the line below in a Perl source file. use MyFilter; In fact, the skeleton modules shown above are fully functional I
, albeit fairly useless ones. All they does is filter the source stream without modifying it at all. As you can see both modules have a broadly similar structure. They both make use of the C
module and both have an C
method. The difference between them is that the I
requires a I
method, whereas the I
gets the equivalent of a I
method with the anonymous sub passed to I
. To make proper use of the I
shown above you need to have a good understanding of the concept of a I
. See L
for more details on the mechanics of I
. =head2 B
The following functions are exported by C
: filter_add() filter_read() filter_read_exact() filter_del() =head2 B
The C
method is used to create an instance of the filter. It is called indirectly by Perl when it encounters the C
line in a source file (See L
for more details on C
). It will always have at least one parameter automatically passed by Perl - this corresponds to the name of the package. In the example above it will be C<"MyFilter">. Apart from the first parameter, import can accept an optional list of parameters. These can be used to pass parameters to the filter. For example: use MyFilter qw(a b c) ; will result in the C<@_> array having the following values: @_ [0] => "MyFilter" @_ [1] => "a" @_ [2] => "b" @_ [3] => "c" Before terminating, the C
function must explicitly install the filter by calling C
. =head2 B
The function, C
, actually installs the filter. It takes one parameter which should be a reference. The kind of reference used will dictate which of the two filter types will be used. If a CODE reference is used then a I
will be assumed. If a CODE reference is not used, a I
will be assumed. In a I
, the reference can be used to store context information. The reference will be I
into the package by C
, unless the reference was already blessed. See the filters at the end of this documents for examples of using context information using both I
and I
. =head2 B
Both the C
method used with a I
and the anonymous sub used with a I
is where the main processing for the filter is done. The big difference between the two types of filter is that the I
uses the object passed to the method to store any context data, whereas the I
uses the lexical variables that are maintained by the closure. Note that the single parameter passed to the I
, C<$self>, is the same reference that was passed to C
blessed into the filter's package. See the example filters later on for details of using C<$self>. Here is a list of the common features of the anonymous sub and the C
method. =over 5 =item B<$_> Although C<$_> doesn't actually appear explicitly in the sample filters above, it is implicitly used in a number of places. Firstly, when either C
or the anonymous sub are called, a local copy of C<$_> will automatically be created. It will always contain the empty string at this point. Next, both C
and C
will append any source data that is read to the end of C<$_>. Finally, when C
or the anonymous sub are finished processing, they are expected to return the filtered source using C<$_>. This implicit use of C<$_> greatly simplifies the filter. =item B<$status> The status value that is returned by the user's C
method or anonymous sub and the C
and C
functions take the same set of values, namely: < 0 Error = 0 EOF > 0 OK =item B
and B
These functions are used by the filter to obtain either a line or block from the next filter in the chain or the actual source file if there aren't any other filters. The function C
takes two forms: $status = filter_read() ; $status = filter_read($size) ; The first form is used to request a I
, the second requests a I
. In line mode, C
will append the next source line to the end of the C<$_> scalar. In block mode, C
will append a block of data which is <= C<$size> to the end of the C<$_> scalar. It is important to emphasise the that C
will not necessarily read a block which is I
C<$size> bytes. If you need to be able to read a block which has an exact size, you can use the function C
. It works identically to C
in block mode, except it will try to read a block which is exactly C<$size> bytes in length. The only circumstances when it will not return a block which is C<$size> bytes long is on EOF or error. It is I
important to check the value of C<$status> after I
call to C
or C
. =item B
The function, C
, is used to disable the current filter. It does not affect the running of the filter. All it does is tell Perl not to call filter any more. See L
for details. =item I
Internal function which adds the filter, based on the L
argument type. =item I
May be used to disable a filter, but is rarely needed. See L
. =back =head1 LIMITATIONS See L
for an overview of the general problems filtering code in a textual line-level only. =over =item __DATA__ is ignored The content from the __DATA__ block is not filtered. This is a serious limitation, e.g. for the L
module. See L
for more. =item Max. codesize limited to 32-bit Currently internal buffer lengths are limited to 32-bit only. =back =head1 EXAMPLES Here are a few examples which illustrate the key concepts - as such most of them are of little practical use. The C
sub-directory has copies of all these filters implemented both as I
and as I
. =head2 Example 1: A simple filter. Below is a I
which is hard-wired to replace all occurrences of the string C<"Joe"> to C<"Jim">. Not particularly Useful, but it is the first example and I wanted to keep it simple. package Joe2Jim ; use Filter::Util::Call ; sub import { my($type) = @_ ; filter_add(bless []) ; } sub filter { my($self) = @_ ; my($status) ; s/Joe/Jim/g if ($status = filter_read()) > 0 ; $status ; } 1 ; Here is an example of using the filter: use Joe2Jim ; print "Where is Joe?\n" ; And this is what the script above will print: Where is Jim? =head2 Example 2: Using the context The previous example was not particularly useful. To make it more general purpose we will make use of the context data and allow any arbitrary I
and I
strings to be used. This time we will use a I
. To reflect its enhanced role, the filter is called C
. package Subst ; use Filter::Util::Call ; use Carp ; sub import { croak("usage: use Subst qw(from to)") unless @_ == 3 ; my ($self, $from, $to) = @_ ; filter_add( sub { my ($status) ; s/$from/$to/ if ($status = filter_read()) > 0 ; $status ; }) } 1 ; and is used like this: use Subst qw(Joe Jim) ; print "Where is Joe?\n" ; =head2 Example 3: Using the context within the filter Here is a filter which a variation of the C
filter. As well as substituting all occurrences of C<"Joe"> to C<"Jim"> it keeps a count of the number of substitutions made in the context object. Once EOF is detected (C<$status> is zero) the filter will insert an extra line into the source stream. When this extra line is executed it will print a count of the number of substitutions actually made. Note that C<$status> is set to C<1> in this case. package Count ; use Filter::Util::Call ; sub filter { my ($self) = @_ ; my ($status) ; if (($status = filter_read()) > 0 ) { s/Joe/Jim/g ; ++ $$self ; } elsif ($$self >= 0) { # EOF $_ = "print q[Made ${$self} substitutions\n]" ; $status = 1 ; $$self = -1 ; } $status ; } sub import { my ($self) = @_ ; my ($count) = 0 ; filter_add(\$count) ; } 1 ; Here is a script which uses it: use Count ; print "Hello Joe\n" ; print "Where is Joe\n" ; Outputs: Hello Jim Where is Jim Made 2 substitutions =head2 Example 4: Using filter_del Another variation on a theme. This time we will modify the C
filter to allow a starting and stopping pattern to be specified as well as the I
and I
patterns. If you know the I
editor, it is the equivalent of this command: :/start/,/stop/s/from/to/ When used as a filter we want to invoke it like this: use NewSubst qw(start stop from to) ; Here is the module. package NewSubst ; use Filter::Util::Call ; use Carp ; sub import { my ($self, $start, $stop, $from, $to) = @_ ; my ($found) = 0 ; croak("usage: use Subst qw(start stop from to)") unless @_ == 5 ; filter_add( sub { my ($status) ; if (($status = filter_read()) > 0) { $found = 1 if $found == 0 and /$start/ ; if ($found) { s/$from/$to/ ; filter_del() if /$stop/ ; } } $status ; } ) } 1 ; =head1 Filter::Simple If you intend using the Filter::Call functionality, I would strongly recommend that you check out Damian Conway's excellent Filter::Simple module. Damian's module provides a much cleaner interface than Filter::Util::Call. Although it doesn't allow the fine control that Filter::Util::Call does, it should be adequate for the majority of applications. It's available at http://search.cpan.org/dist/Filter-Simple/ =head1 AUTHOR Paul Marquess =head1 DATE 26th January 1996 =head1 LICENSE Copyright (c) 1995-2011 Paul Marquess. All rights reserved. Copyright (c) 2011-2014, 2018-2022 Reini Urban. All rights reserved. Copyright (c) 2014-2017 cPanel Inc. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. =cut