This file is indexed.

/usr/share/perl5/PPI/Find.pm is in libppi-perl 1.236-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
package PPI::Find;

=pod

=head1 NAME

PPI::Find - Object version of the Element->find method

=head1 SYNOPSIS

  # Create the Find object
  my $Find = PPI::Find->new( \&wanted );
  
  # Return all matching Elements as a list
  my @found = $Find->in( $Document );
  
  # Can we find any matching Elements
  if ( $Find->any_matches($Document) ) {
  	print "Found at least one matching Element";
  }
  
  # Use the object as an iterator
  $Find->start($Document) or die "Failed to execute search";
  while ( my $token = $Find->match ) {
  	...
  }

=head1 DESCRIPTION

PPI::Find is the primary PDOM searching class in the core PPI package.

=head2 History

It became quite obvious during the development of PPI that many of the
modules that would be built on top of it were going to need large numbers
of saved, storable or easily creatable search objects that could be
reused a number of times.

Although the internal ->find method provides a basic ability to search,
it is by no means thorough. PPI::Find attempts to resolve this problem.

=head2 Structure and Style

PPI::Find provides a similar API to the popular L<File::Find::Rule>
module for file searching, but without the ability to assemble queries.

The implementation of a separate PPI::Find::Rule sub-class that does
provide this ability is left as an exercise for the reader.

=head2 The &wanted function

At the core of each PPI::Find object is a "wanted" function that is
passed a number of arguments and returns a value which controls the
flow of the search.

As the search executes, each Element will be passed to the wanted function
in depth-first order.

It will be provided with two arguments. The current Element to test as $_[0],
and the top-level Element of the search as $_[1].

The &wanted function is expected to return 1 (positive) if the Element
matches the condition, 0 (false) if it does not, and undef (undefined) if
the condition does not match, and the Find search should not descend to
any of the current Element's children.

Errors should be reported from the &wanted function via die, which will be
caught by the Find object and returned as an error.

=head1 METHODS

=cut

use strict;
use Params::Util qw{_INSTANCE};

use vars qw{$VERSION};
BEGIN {
	$VERSION = '1.236';
}





#####################################################################
# Constructor

=pod

=head2 new &wanted

The C<new> constructor takes a single argument of the &wanted function,
as described above and creates a new search.

Returns a new PPI::Find object, or C<undef> if not passed a CODE reference.

=cut

sub new {
	my $class  = ref $_[0] ? ref shift : shift;
	my $wanted = ref $_[0] eq 'CODE' ? shift : return undef;

	# Create the object
	my $self = bless {
		wanted => $wanted,
	}, $class;

	$self;
}

=pod

=head2 clone

The C<clone> method creates another instance of the same Find object.

The cloning is done safely, so if your existing Find object is in the
middle of an iteration, the cloned Find object will not also be in the
iteration and can be safely used independently.

Returns a duplicate PPI::Find object.

=cut

sub clone {
	my $self = ref $_[0] ? shift
		: die "->clone can only be called as an object method";
	my $class = ref $self;

	# Create the object
	my $clone = bless {
		wanted => $self->{wanted},
	}, $class;

	$clone;
}





####################################################################
# Search Execution Methods

=pod

=head2 in $Document [, array_ref => 1 ]

The C<in> method starts and completes a full run of the search.

It takes as argument a single L<PPI::Element> object which will
serve as the top of the search process.

Returns a list of PPI::Element objects that match the condition
described by the &wanted function, or the null list on error.

You should check the ->errstr method for any errors if you are
returned the null list, which may also mean simply that no Elements
were found that matched the condition.

Because of this need to explicitly check for errors, an alternative
return value mechanism is provide. If you pass the C<< array_ref => 1 >>
parameter to the method, it will return the list of matched Elements
as a reference to an ARRAY. The method will return false if no elements
were matched, or C<undef> on error.

The ->errstr method can still be used to get the error message as normal.

=cut

sub in {
	my $self    = shift;
	my $Element = shift;
	my %params  = @_;
	delete $self->{errstr};
 
	# Are we already acting as an iterator
	if ( $self->{in} ) {
		return $self->_error('->in called while another search is in progress', %params);
	}

	# Get the root element for the search
	unless ( _INSTANCE($Element, 'PPI::Element') ) {
		return $self->_error('->in was not passed a PPI::Element object', %params);
	}

	# Prepare the search
	$self->{in}      = $Element;
	$self->{matches} = [];

	# Execute the search
	if ( !eval { $self->_execute; 1 } ) {
		my $errstr = $@;
		$errstr =~ s/\s+at\s+line\s+.+$//;
		return $self->_error("Error while searching: $errstr", %params);
	}

	# Clean up and return
	delete $self->{in};
	if ( $params{array_ref} ) {
		if ( @{$self->{matches}} ) {
			return delete $self->{matches};
		}
		delete $self->{matches};
		return '';
	}

	# Return as a list
	my $matches = delete $self->{matches};
	@$matches;
}

=pod

=head2 start $Element

The C<start> method lets the Find object act as an iterator. The method
is passed the parent PPI::Element object as for the C<in> method, but does
not accept any parameters.

To simplify error handling, the entire search is done at once, with the
results cached and provided as-requested.

Returns true if the search completes, and false on error.

=cut

sub start {
	my $self    = shift;
	my $Element = shift;
	delete $self->{errstr};

	# Are we already acting as an iterator
	if ( $self->{in} ) {
		return $self->_error('->in called while another search is in progress');
	}

	# Get the root element for the search
	unless ( _INSTANCE($Element, 'PPI::Element') ) {
		return $self->_error('->in was not passed a PPI::Element object');
	}

	# Prepare the search
	$self->{in}      = $Element;
	$self->{matches} = [];

	# Execute the search
	if ( !eval { $self->_execute; 1 } ) {
		my $errstr = $@;
		$errstr =~ s/\s+at\s+line\s+.+$//;
		$self->_error("Error while searching: $errstr");
		return undef;
	}

	1;
}

=pod

=head2 match

The C<match> method returns the next matching Element in the iteration.

Returns a PPI::Element object, or C<undef> if there are no remaining
Elements to be returned.

=cut

sub match {
	my $self = shift;
	return undef unless $self->{matches};

	# Fetch and return the next match
	my $match = shift @{$self->{matches}};
	return $match if $match;

	$self->finish;
	undef;
}

=pod

=head2 finish

The C<finish> method provides a mechanism to end iteration if you wish to
stop the iteration prematurely. It resets the Find object and allows it to
be safely reused.

A Find object will be automatically finished when C<match> returns false.
This means you should only need to call C<finish> when you stop
iterating early.

You may safely call this method even when not iterating and it will return
without failure.

Always returns true

=cut

sub finish {
	my $self = shift;
	delete $self->{in};
	delete $self->{matches};
	delete $self->{errstr};
	1;
}





#####################################################################
# Support Methods and Error Handling

sub _execute {
	my $self   = shift;
	my $wanted = $self->{wanted};
	my @queue  = ( $self->{in} );

	# Pull entries off the queue and hand them off to the wanted function
	while ( my $Element = shift @queue ) {
		my $rv = &$wanted( $Element, $self->{in} );

		# Add to the matches if returns true
		push @{$self->{matches}}, $Element if $rv;

		# Continue and don't descend if it returned undef
		# or if it doesn't have children
		next unless defined $rv;
		next unless $Element->isa('PPI::Node');

		# Add the children to the head of the queue
		if ( $Element->isa('PPI::Structure') ) {
			unshift @queue, $Element->finish if $Element->finish;
			unshift @queue, $Element->children;
			unshift @queue, $Element->start if $Element->start;
		} else {
			unshift @queue, $Element->children;
		}
	}

	1;
}

=pod

=head2 errstr

The C<errstr> method returns the error messages when a given PPI::Find
object fails any action.

Returns a string, or C<undef> if there is no error.

=cut

sub errstr {
	shift->{errstr};
}

sub _error {
	my $self = shift;
	$self->{errstr} = shift;
	my %params = @_;
	$params{array_ref} ? undef : ();
}

1;

=pod

=head1 TO DO

- Implement the L<PPI::Find::Rule> class

=head1 SUPPORT

See the L<support section|PPI/SUPPORT> in the main module.

=head1 AUTHOR

Adam Kennedy E<lt>adamk@cpan.orgE<gt>

=head1 COPYRIGHT

Copyright 2001 - 2011 Adam Kennedy.

This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.

The full text of the license can be found in the
LICENSE file included with this module.

=cut