PPI

 view release on metacpan or  search on metacpan

lib/PPI/Tokenizer.pm  view on Meta::CPAN

of the token stream.

Return true if the cursor is decremented, C<0> if already at the
beginning of the file, or C<undef> on error.

=cut

sub decrement_cursor {
	my $self = shift;

	# Check for the beginning of the file
	return 0 unless $self->{token_cursor};

	# Decrement the token cursor
	$self->{token_eof} = 0;
	--$self->{token_cursor};
}





#####################################################################
# Working With Source

# Fetches the next line from the input line buffer
# Returns undef at EOF.
sub _get_line {
	my $self = shift;
	return undef unless $self->{source}; # EOF hit previously

	# Pull off the next line
	my $line = shift @{$self->{source}};

	# Flag EOF if we hit it
	$self->{source} = undef unless defined $line;

	# Return the line (or EOF flag)
	return $line; # string or undef
}

# Fetches the next line, ready to process
# Returns 1 on success
# Returns 0 on EOF
sub _fill_line {
	my $self   = shift;
	my $inscan = shift;

	# Get the next line
	my $line = $self->_get_line;
	unless ( defined $line ) {
		# End of file
		unless ( $inscan ) {
			delete $self->{line};
			delete $self->{line_cursor};
			delete $self->{line_length};
			return 0;
		}

		# In the scan version, just set the cursor to the end
		# of the line, and the rest should just cascade out.
		$self->{line_cursor} = $self->{line_length};
		return 0;
	}

	# Populate the appropriate variables
	$self->{line}        = $line;
	$self->{line_cursor} = -1;
	$self->{line_length} = length $line;
	$self->{line_count}++;

	1;
}

# Get the current character
sub _char {
	my $self = shift;
	substr( $self->{line}, $self->{line_cursor}, 1 );
}





####################################################################
# Per line processing methods

# Processes the next line
# Returns 1 on success completion
# Returns 0 if EOF
# Returns undef on error
sub _process_next_line {
	my $self = shift;

	# Fill the line buffer
	my $rv;
	unless ( $rv = $self->_fill_line ) {
		return undef unless defined $rv;

		# End of file, finalize last token
		$self->_finalize_token;
		return 0;
	}

	# Run the __TOKENIZER__on_line_start
	$rv = $self->{class}->__TOKENIZER__on_line_start( $self );
	unless ( $rv ) {
		# If there are no more source lines, then clean up
		if ( ref $self->{source} eq 'ARRAY' and ! @{$self->{source}} ) {
			$self->_clean_eof;
		}

		# Defined but false means next line
		return 1 if defined $rv;
		PPI::Exception->throw("Error at line $self->{line_count}");
	}

	# If we can't deal with the entire line, process char by char
	while ( $rv = $self->_process_next_char ) {}
	unless ( defined $rv ) {
		PPI::Exception->throw("Error at line $self->{line_count}, character $self->{line_cursor}");



( run in 1.298 second using v1.01-cache-2.11-cpan-f56aa216473 )