package TmplTokenizer;
use strict;
+#use warnings; FIXME - Bug 2505
use TmplTokenType;
use TmplToken;
use VerboseWarnings qw( pedantic_p error_normal warn_normal warn_pedantic );
# Hideous stuff
use vars qw( $re_directive $re_tmpl_var $re_tmpl_var_escaped $re_tmpl_include );
-use vars qw( $re_directive_control $re_tmpl_endif_endloop );
+use vars qw( $re_directive_control $re_tmpl_endif_endloop $re_xsl);
BEGIN {
# $re_directive must not do any backreferences
$re_directive = q{<(?:(?i)(?:!--\s*)?\/?TMPL_(?:VAR|LOOP|INCLUDE|IF|ELSE|UNLESS)(?:\s+(?:[a-zA-Z][-a-zA-Z0-9]*=)?(?:'[^']*'|"[^"]*"|[^\s<>]+))*\s*(?:--)?)>};
$re_tmpl_var = q{<(?:(?i)(?:!--\s*)?TMPL_(?:VAR)(?:\s+(?:[a-zA-Z][-a-zA-Z0-9]*=)?(?:'[^']*'|"[^"]*"|[^\s<>]+))*\s*(?:--)?)>};
$re_tmpl_include = q{<(?:(?i)(?:!--\s*)?TMPL_(?:INCLUDE)(?:\s+(?:[a-zA-Z][-a-zA-Z0-9]*=)?(?:'[^']*'|"[^"]*"|[^\s<>]+))*\s*(?:--)?)>};
# TMPL_VAR ESCAPE=1/HTML/URL
+ $re_xsl = q{<\/?(?:xsl:)(?:[\s\-a-zA-Z0-9"'\/\.\[\]\@\(\):=,$]+)\/?>};
$re_tmpl_var_escaped = q{<(?:(?i)(?:!--\s*)?TMPL_(?:VAR|INCLUDE)(?:\s+(?:[a-zA-Z][-a-zA-Z0-9]*=)?(?:'[^']*'|"[^"]*"|[^\s<>]+))\s+ESCAPE=(?:1|HTML|URL)(?:\s+(?:[a-zA-Z][-a-zA-Z0-9]*=)?(?:'[^']*'|"[^"]*"|[^\s<>]+))*\s*(?:--)?)>};
# Any control flow directive
$re_directive_control = q{<(?:(?i)(?:!--\s*)?\/?TMPL_(?:LOOP|IF|ELSE|UNLESS)(?:\s+(?:[a-zA-Z][-a-zA-Z0-9]*=)?(?:'[^']*'|"[^"]*"|[^\s<>]+))*\s*(?:--)?)>};
sub ALLOW_CFORMAT_P () {'allow-cformat-p'}
sub new {
- my $this = shift;
- my($input) = @_;
- my $class = ref($this) || $this;
- my $self = {};
- bless $self, $class;
-
- my $handle = sprintf('TMPLTOKENIZER%d', $serial);
- $serial += 1;
-
- no strict;
- open($handle, "<$input") || die "$input: $!\n";
- use strict;
- $self->{+FILENAME} = $input;
- $self->{+HANDLE} = $handle;
- $self->{+READAHEAD} = [];
- return $self;
+ shift;
+ my ($filename) = @_;
+ open my $handle,$filename or die "can't open $filename";
+ bless {
+ filename => $filename
+ , handle => $handle
+ , readahead => []
+ } , __PACKAGE__;
}
###############################################################################
sub filename {
my $this = shift;
- return $this->{+FILENAME};
+ return $this->{filename};
}
sub _handle {
my $this = shift;
- return $this->{+HANDLE};
+ return $this->{handle};
}
sub fatal_p {
sub has_readahead_p {
my $this = shift;
- return @{$this->{+READAHEAD}};
+ return @{$this->{readahead}};
}
sub _peek_readahead {
my $this = shift;
- return $this->{+READAHEAD}->[$#{$this->{+READAHEAD}}];
+ return $this->{readahead}->[$#{$this->{readahead}}];
}
sub line_number_start {
sub _push_readahead {
my $this = shift;
- push @{$this->{+READAHEAD}}, $_[0];
+ push @{$this->{readahead}}, $_[0];
return $this;
}
sub _pop_readahead {
my $this = shift;
- return pop @{$this->{+READAHEAD}};
+ return pop @{$this->{readahead}};
}
sub _append_readahead {
my $this = shift;
- $this->{+READAHEAD}->[$#{$this->{+READAHEAD}}] .= $_[0];
+ $this->{readahead}->[$#{$this->{readahead}}] .= $_[0];
return $this;
}
sub _set_readahead {
my $this = shift;
- $this->{+READAHEAD}->[$#{$this->{+READAHEAD}}] = $_[0];
+ $this->{readahead}->[$#{$this->{readahead}}] = $_[0];
return $this;
}
sub blank_p ($) {
my($s) = @_;
- return $s =~ /^(?:\s|\ $re_end_entity|$re_tmpl_var)*$/os;
+ return $s =~ /^(?:\s|\ $re_end_entity|$re_tmpl_var|$re_xsl)*$/os;
}
sub trim ($) {
=item S
Specifies a text input field (<INPUT TYPE=TEXT>).
-This use of the o conversion specifier is somewhat reasonable,
+This use of the S conversion specifier is somewhat reasonable,
since text input fields contain values of undeterminable type,
which can be treated as strings.