This file is indexed.

/usr/lib/perl5/Template/Iterator.pm is in libtemplate-perl 2.24-1.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
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
#============================================================= -*-Perl-*-
#
# Template::Iterator
#
# DESCRIPTION
#
#   Module defining an iterator class which is used by the FOREACH
#   directive for iterating through data sets.  This may be
#   sub-classed to define more specific iterator types.
#
# AUTHOR
#   Andy Wardley   <abw@wardley.org>
#
# COPYRIGHT
#   Copyright (C) 1996-2007 Andy Wardley.  All Rights Reserved.
#
#   This module is free software; you can redistribute it and/or
#   modify it under the same terms as Perl itself.
#
#============================================================================

package Template::Iterator;

use strict;
use warnings;
use base 'Template::Base';
use Template::Constants;
use Template::Exception;
use Scalar::Util qw(blessed);

use constant ODD  => 'odd';
use constant EVEN => 'even';

our $VERSION = 2.68;
our $DEBUG   = 0 unless defined $DEBUG;
our $AUTOLOAD;

#========================================================================
#                      -----  CLASS METHODS -----
#========================================================================

#------------------------------------------------------------------------
# new(\@target, \%options)
#
# Constructor method which creates and returns a reference to a new 
# Template::Iterator object.  A reference to the target data (array
# or hash) may be passed for the object to iterate through.
#------------------------------------------------------------------------

sub new {
    my $class  = shift;
    my $data   = shift || [ ];
    my $params = shift || { };

    if (ref $data eq 'HASH') {
        # map a hash into a list of { key => ???, value => ??? } hashes,
        # one for each key, sorted by keys
        $data = [ map { { key => $_, value => $data->{ $_ } } }
                  sort keys %$data ];
    }
    elsif (blessed($data) && $data->can('as_list')) {
        $data = $data->as_list();
    }
    elsif (ref $data ne 'ARRAY') {
        # coerce any non-list data into an array reference
        $data  = [ $data ] ;
    }

    bless {
        _DATA  => $data,
        _ERROR => '',
    }, $class;
}


#========================================================================
#                   -----  PUBLIC OBJECT METHODS -----
#========================================================================

#------------------------------------------------------------------------
# get_first()
#
# Initialises the object for iterating through the target data set.  The 
# first record is returned, if defined, along with the STATUS_OK value.
# If there is no target data, or the data is an empty set, then undef 
# is returned with the STATUS_DONE value.  
#------------------------------------------------------------------------

sub get_first {
    my $self  = shift;
    my $data  = $self->{ _DATA };

    $self->{ _DATASET } = $self->{ _DATA };
    my $size = scalar @$data;
    my $index = 0;
    
    return (undef, Template::Constants::STATUS_DONE) unless $size;

    # initialise various counters, flags, etc.
    @$self{ qw( SIZE MAX INDEX COUNT FIRST LAST ) } 
            = ( $size, $size - 1, $index, 1, 1, $size > 1 ? 0 : 1, undef );
    @$self{ qw( PREV NEXT ) } = ( undef, $self->{ _DATASET }->[ $index + 1 ]);

    return $self->{ _DATASET }->[ $index ];
}



#------------------------------------------------------------------------
# get_next()
#
# Called repeatedly to access successive elements in the data set.
# Should only be called after calling get_first() or a warning will 
# be raised and (undef, STATUS_DONE) returned.
#------------------------------------------------------------------------

sub get_next {
    my $self = shift;
    my ($max, $index) = @$self{ qw( MAX INDEX ) };
    my $data = $self->{ _DATASET };

    # warn about incorrect usage
    unless (defined $index) {
        my ($pack, $file, $line) = caller();
        warn("iterator get_next() called before get_first() at $file line $line\n");
        return (undef, Template::Constants::STATUS_DONE);   ## RETURN ##
    }

    # if there's still some data to go...
    if ($index < $max) {
        # update counters and flags
        $index++;
        @$self{ qw( INDEX COUNT FIRST LAST ) }
        = ( $index, $index + 1, 0, $index == $max ? 1 : 0 );
        @$self{ qw( PREV NEXT ) } = @$data[ $index - 1, $index + 1 ];
        return $data->[ $index ];                           ## RETURN ##
    }
    else {
        return (undef, Template::Constants::STATUS_DONE);   ## RETURN ##
    }
}


#------------------------------------------------------------------------
# get_all()
#
# Method which returns all remaining items in the iterator as a Perl list
# reference.  May be called at any time in the life-cycle of the iterator.
# The get_first() method will be called automatically if necessary, and
# then subsequent get_next() calls are made, storing each returned 
# result until the list is exhausted.  
#------------------------------------------------------------------------

sub get_all {
    my $self = shift;
    my ($max, $index) = @$self{ qw( MAX INDEX ) };
    my @data;

    # handle cases where get_first() has yet to be called.
    unless (defined $index) {
        my ($first, $status) = $self->get_first;

        # refresh $max and $index, after get_first updates MAX and INDEX
        ($max, $index) = @$self{ qw( MAX INDEX ) };

        # empty lists are handled here.
        if ($status && $status == Template::Constants::STATUS_DONE) {
            return (undef, Template::Constants::STATUS_DONE);   ## RETURN ##
        }

        push @data, $first;

        ## if there's nothing left in the iterator, return the single value.
        unless ($index < $max) {
            return \@data;
        }
    }

    # if there's still some data to go...
    if ($index < $max) {
        $index++;
        push @data, @{ $self->{ _DATASET } } [ $index..$max ];
        
        # update counters and flags
        @$self{ qw( INDEX COUNT FIRST LAST ) }
        = ( $max, $max + 1, 0, 1 );

        return \@data;                                      ## RETURN ##
    }
    else {
        return (undef, Template::Constants::STATUS_DONE);   ## RETURN ##
    }
}

sub odd {
    shift->{ COUNT } % 2 ? 1 : 0
}

sub even {
    shift->{ COUNT } % 2 ? 0 : 1
}

sub parity {
    shift->{ COUNT } % 2 ? ODD : EVEN;
}


#------------------------------------------------------------------------
# AUTOLOAD
#
# Provides access to internal fields (e.g. size, first, last, max, etc)
#------------------------------------------------------------------------

sub AUTOLOAD {
    my $self = shift;
    my $item = $AUTOLOAD;
    $item =~ s/.*:://;
    return if $item eq 'DESTROY';

    # alias NUMBER to COUNT for backwards compatability
    $item = 'COUNT' if $item =~ /NUMBER/i;

    return $self->{ uc $item };
}


#========================================================================
#                   -----  PRIVATE DEBUG METHODS -----
#========================================================================

#------------------------------------------------------------------------
# _dump()
#
# Debug method which returns a string detailing the internal state of 
# the iterator object.
#------------------------------------------------------------------------

sub _dump {
    my $self = shift;
    join('',
         "  Data: ", $self->{ _DATA  }, "\n",
         " Index: ", $self->{ INDEX  }, "\n",
         "Number: ", $self->{ NUMBER }, "\n",
         "   Max: ", $self->{ MAX    }, "\n",
         "  Size: ", $self->{ SIZE   }, "\n",
         " First: ", $self->{ FIRST  }, "\n",
         "  Last: ", $self->{ LAST   }, "\n",
         "\n"
     );
}


1;

__END__

=head1 NAME

Template::Iterator - Data iterator used by the FOREACH directive

=head1 SYNOPSIS

    my $iter = Template::Iterator->new(\@data, \%options);

=head1 DESCRIPTION

The C<Template::Iterator> module defines a generic data iterator for use 
by the C<FOREACH> directive.  

It may be used as the base class for custom iterators.

=head1 PUBLIC METHODS

=head2 new($data) 

Constructor method.  A reference to a list of values is passed as the
first parameter.  Subsequent calls to L<get_first()> and L<get_next()> calls 
will return each element from the list.

    my $iter = Template::Iterator->new([ 'foo', 'bar', 'baz' ]);

The constructor will also accept a reference to a hash array and will 
expand it into a list in which each entry is a hash array containing
a 'C<key>' and 'C<value>' item, sorted according to the hash keys.

    my $iter = Template::Iterator->new({ 
        foo => 'Foo Item',
        bar => 'Bar Item',
    });

This is equivalent to:

    my $iter = Template::Iterator->new([
        { key => 'bar', value => 'Bar Item' },
        { key => 'foo', value => 'Foo Item' },
    ]);

When passed a single item which is not an array reference, the constructor
will automatically create a list containing that single item.

    my $iter = Template::Iterator->new('foo');

This is equivalent to:

    my $iter = Template::Iterator->new([ 'foo' ]);

Note that a single item which is an object based on a blessed ARRAY 
references will NOT be treated as an array and will be folded into 
a list containing that one object reference.

    my $list = bless [ 'foo', 'bar' ], 'MyListClass';
    my $iter = Template::Iterator->new($list);

equivalent to:

    my $iter = Template::Iterator->new([ $list ]);

If the object provides an C<as_list()> method then the L<Template::Iterator>
constructor will call that method to return the list of data.  For example:

    package MyListObject;
    
    sub new {
        my $class = shift;
        bless [ @_ ], $class;
    }

    package main;
    
    my $list = MyListObject->new('foo', 'bar');
    my $iter = Template::Iterator->new($list);

This is then functionally equivalent to:

    my $iter = Template::Iterator->new([ $list ]);

The iterator will return only one item, a reference to the C<MyListObject>
object, C<$list>.

By adding an C<as_list()> method to the C<MyListObject> class, we can force
the C<Template::Iterator> constructor to treat the object as a list and 
use the data contained within.

    package MyListObject;
    
    ...
    
    sub as_list {
        my $self = shift;
        return $self;
    }
    
    package main;
    
    my $list = MyListObject->new('foo', 'bar');
    my $iter = Template::Iterator->new($list);

The iterator will now return the two items, 'C<foo>' and 'C<bar>', which the 
C<MyObjectList> encapsulates.

=head2 get_first()

Returns a C<($value, $error)> pair for the first item in the iterator set.
The C<$error> returned may be zero or undefined to indicate a valid datum
was successfully returned.  Returns an error of C<STATUS_DONE> if the list 
is empty.

=head2 get_next()

Returns a C<($value, $error)> pair for the next item in the iterator set.
Returns an error of C<STATUS_DONE> if all items in the list have been 
visited.

=head2 get_all()

Returns a C<(\@values, $error)> pair for all remaining items in the iterator 
set.  Returns an error of C<STATUS_DONE> if all items in the list have been 
visited.

=head2 size()

Returns the size of the data set or undef if unknown.

=head2 max()

Returns the maximum index number (i.e. the index of the last element) 
which is equivalent to L<size()> - C<1>.

=head2 index()

Returns the current index number which is in the range C<0> to L<max()>.

=head2 count()

Returns the current iteration count in the range C<1> to L<size()>.  This is
equivalent to L<index()> + C<1>.  

=head2 first()

Returns a boolean value to indicate if the iterator is currently on 
the first iteration of the set.

=head2 last()

Returns a boolean value to indicate if the iterator is currently on
the last iteration of the set.

=head2 prev()

Returns the previous item in the data set, or C<undef> if the iterator is
on the first item.

=head2 next()

Returns the next item in the data set or C<undef> if the iterator is on the 
last item.

=head2 parity()

Returns the text string C<even> or C<odd> to indicate the parity of the 
current iteration count (starting at 1).  This is typically used to create
striped I<zebra tables>.

    <table>
    [% FOREACH name IN ['Arthur', 'Ford', 'Trillian'] -%]
      <tr class="[% loop.parity %]">
        <td>[% name %]</td>
      </tr>
    [% END %]
    </table>

This will produce the following output:

    <table>
      <tr class="odd">
        <td>Arthur</td>
      </tr>
      <tr class="even">
        <td>Ford</td>
      </tr>
      <tr class="odd">
        <td>Trillian</td>
      </tr>
    </table>

You can then style the C<tr.odd> and C<tr.even> elements using CSS:

    tr.odd td {
        background-color: black;
        color: white;
    }
    
    tr.even td {
        background-color: white;
        color: black;
    }

=head2 odd()

Returns a boolean (0/1) value to indicate if the current iterator count
(starting at 1) is an odd number. In other words, this will return a true
value for the first iterator, the third, fifth, and so on.

=head2 even()

Returns a boolean (0/1) value to indicate if the current iterator count
(starting at 1) is an even number. In other words, this will return a true
value for the second iteration, the fourth, sixth, and so on.

=head1 AUTHOR

Andy Wardley E<lt>abw@wardley.orgE<gt> L<http://wardley.org/>

=head1 COPYRIGHT

Copyright (C) 1996-2007 Andy Wardley.  All Rights Reserved.

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

=head1 SEE ALSO

L<Template>

=cut

# Local Variables:
# mode: perl
# perl-indent-level: 4
# indent-tabs-mode: nil
# End:
#
# vim: expandtab shiftwidth=4: