summaryrefslogtreecommitdiff
path: root/systems/texlive/tlnet/tlpkg/tlperl/lib/TAP/Parser/Iterator.pm
blob: fab48cb2bed288799b732c11d40d0628184f2ef8 (plain)
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
package TAP::Parser::Iterator;

use strict;
use warnings;

use base 'TAP::Object';

=head1 NAME

TAP::Parser::Iterator - Base class for TAP source iterators

=head1 VERSION

Version 3.42

=cut

our $VERSION = '3.42';

=head1 SYNOPSIS

  # to subclass:
  use TAP::Parser::Iterator ();
  use base 'TAP::Parser::Iterator';
  sub _initialize {
    # see TAP::Object...
  }

  sub next_raw { ... }
  sub wait     { ... }
  sub exit     { ... }

=head1 DESCRIPTION

This is a simple iterator base class that defines L<TAP::Parser>'s iterator
API.  Iterators are typically created from L<TAP::Parser::SourceHandler>s.

=head1 METHODS

=head2 Class Methods

=head3 C<new>

Create an iterator.  Provided by L<TAP::Object>.

=head2 Instance Methods

=head3 C<next>

 while ( my $item = $iter->next ) { ... }

Iterate through it, of course.

=head3 C<next_raw>

B<Note:> this method is abstract and should be overridden.

 while ( my $item = $iter->next_raw ) { ... }

Iterate raw input without applying any fixes for quirky input syntax.

=cut

sub next {
    my $self = shift;
    my $line = $self->next_raw;

    # vms nit:  When encountering 'not ok', vms often has the 'not' on a line
    # by itself:
    #   not
    #   ok 1 - 'I hate VMS'
    if ( defined($line) and $line =~ /^\s*not\s*$/ ) {
        $line .= ( $self->next_raw || '' );
    }

    return $line;
}

sub next_raw {
    require Carp;
    my $msg = Carp::longmess('abstract method called directly!');
    $_[0]->_croak($msg);
}

=head3 C<handle_unicode>

If necessary switch the input stream to handle unicode. This only has
any effect for I/O handle based streams.

The default implementation does nothing.

=cut

sub handle_unicode { }

=head3 C<get_select_handles>

Return a list of filehandles that may be used upstream in a select()
call to signal that this Iterator is ready. Iterators that are not
handle-based should return an empty list.

The default implementation does nothing.

=cut

sub get_select_handles {
    return;
}

=head3 C<wait>

B<Note:> this method is abstract and should be overridden.

 my $wait_status = $iter->wait;

Return the C<wait> status for this iterator.

=head3 C<exit>

B<Note:> this method is abstract and should be overridden.

 my $wait_status = $iter->exit;

Return the C<exit> status for this iterator.

=cut

sub wait {
    require Carp;
    my $msg = Carp::longmess('abstract method called directly!');
    $_[0]->_croak($msg);
}

sub exit {
    require Carp;
    my $msg = Carp::longmess('abstract method called directly!');
    $_[0]->_croak($msg);
}

1;

=head1 SUBCLASSING

Please see L<TAP::Parser/SUBCLASSING> for a subclassing overview.

You must override the abstract methods as noted above.

=head2 Example

L<TAP::Parser::Iterator::Array> is probably the easiest example to follow.
There's not much point repeating it here.

=head1 SEE ALSO

L<TAP::Object>,
L<TAP::Parser>,
L<TAP::Parser::Iterator::Array>,
L<TAP::Parser::Iterator::Stream>,
L<TAP::Parser::Iterator::Process>,

=cut