# FileParser.pm - general file line-oriented reading/parsing routines
# (c) Martin Matousek, 2003-11-18

=head1 NAME

FileParser - general file line-oriented reading/parsing routines

=head1 SYNOPSIS

use FileParser;

=head1 DESCRIPTION

=head2 Members

=over 4

=item $scr->{ 'Rows' };

=item $scr->{ 'Cols' };

=back

=head2 Methods

=over 4

=cut

use strict;
use warnings;

package FileParser;
use FileHandle;

=item $parser = new FileParser;

Constructor 

=cut
sub  new
{
    return bless( {}, ref( $_[0] ) || $_[0] );
}


=item $fl = $parser->fl();

=cut
sub fl 
{
    defined( $_[0]->{'file'} ) ? "$_[0]->{ 'file' }:$_[0]->{ 'line' }" : "???";
}


=item $fl = $parser->warn( $text, ... );

=cut
sub warn
{
    my $this = shift;
    $this->{'opts'}{'nowarn'} or
        print STDERR $this->fl(), ': ', @_, "\n";
}

=item $fl = $parser->die( $text, ... );

=cut
sub die
{
    my $this = shift;
    CORE::die( $this->fl(), ': ', @_, "\n" );
}


=item $parser->open( $filename [,$binmode] );

=cut
sub open
{
    my( $this, $file, $binmode ) = @_;

    $this->{ 'fh' } = new FileHandle( $file,"r" ) or
        CORE::die( "cannot ropen file \"$file\"." );

    $binmode and binmode( $this->{'fh'}, $binmode );
    $this->{'file'} = $file;
    $this->{'line'} = 0;       # line counter
    $this->{'row'} = '';
}

=item $parser->readline( \&row_dispatch );

=cut
sub readline
{
    my( $this, $dispatch) = @_;
    my $row = '';

    while( $row eq '' )
    {
        $row = $this->{ 'fh' }->getline() || return 0;
        ++ $this->{ 'line' };

        defined( $dispatch ) and $row = &$dispatch( $row );
    }

    $this->{'row'} .= $row;
    return 1;
}


=item $row = $parser->row( \&row_dispatch [,old_row_content] );

=cut
sub row
{
    my ( $this, $dispatch, $row )  = @_;

    defined( $row ) and $this->{'row'} = $row;
   
    while( $this->{'row'} eq '')
    {
        if( ! $this->readline( $dispatch ) )
        {
            return undef;
        }
    }

    return $this->{'row'};
}


=item $parser->close();

=cut
sub close
{
    my( $this) = @_;
    $this->{'fh'}->close();
    undef $this->{'file'};
}

1;
