File Coverage

blib/lib/Syntax/Highlight/Engine/Kate/Template.pm
Criterion Covered Total %
statement 519 577 89.9
branch 181 234 77.3
condition 16 18 88.8
subroutine 73 73 100.0
pod 57 63 90.4
total 846 965 87.6


line stmt bran cond sub pod time code
1             # Copyright (c) 2006 Hans Jeuken. All rights reserved.
2             # This program is free software; you can redistribute it and/or
3             # modify it under the same terms as Perl itself.
4              
5             package Syntax::Highlight::Engine::Kate::Template;
6              
7             our $VERSION = '0.16';
8              
9 9     9   80 use strict;
  9         51  
  9         430  
10 9     9   77 use Carp qw(cluck);
  9         19  
  9         509  
11 9     9   1461 use Data::Dumper;
  9         24725  
  9         56455  
12              
13             #my $regchars = '\\^.$|()[]*+?';
14              
15             sub new {
16 239     239 0 780 my $proto = shift;
17 239   33     1315 my $class = ref($proto) || $proto;
18 239         1192 my %args = (@_);
19              
20 239         720 my $debug = delete $args{'debug'};
21 239 50       856 unless (defined($debug)) { $debug = 0 };
  239         553  
22 239         618 my $substitutions = delete $args{'substitutions'};
23 239 100       838 unless (defined($substitutions)) { $substitutions = {} };
  108         305  
24 239         631 my $formattable = delete $args{'format_table'};
25 239 100       801 unless (defined($formattable)) { $formattable = {} };
  97         285  
26 239         585 my $engine = delete $args{'engine'};
27              
28 239         501 my $self = {};
29             $self->{'attributes'} = {},
30 239         1802 $self->{'captured'} = [];
31 239         1308 $self->{'contextdata'} = {};
32 239         657 $self->{'basecontext'} = '';
33 239         677 $self->{'debug'} = $debug;
34 239         1335 $self->{'deliminators'} = '';
35 239         967 $self->{'engine'} = '';
36 239         627 $self->{'format_table'} = $formattable;
37 239         611 $self->{'keywordscase'} = 1;
38 239         632 $self->{'lastchar'} = '';
39 239         751 $self->{'linesegment'} = '';
40 239         869 $self->{'lists'} = {};
41 239         671 $self->{'linestart'} = 1;
42 239         742 $self->{'out'} = [];
43 239         669 $self->{'plugins'} = {};
44 239         657 $self->{'snippet'} = '';
45 239         1130 $self->{'snippetattribute'} = '';
46 239         557 $self->{'stack'} = [];
47 239         585 $self->{'substitutions'} = $substitutions;
48 239         1306 bless ($self, $class);
49 239 100       2178 unless (defined $engine) { $engine = $self };
  150         330  
50 239         1725 $self->engine($engine);
51 239         1571 $self->initialize;
52 239         1007 return $self;
53             }
54              
55             sub attributes {
56 226     226 1 570 my $self = shift;
57 226 50       782 if (@_) { $self->{'attributes'} = shift; };
  226         702  
58 226         644 return $self->{'attributes'};
59             }
60              
61             sub basecontext {
62 340     340 1 749 my $self = shift;
63 340 100       989 if (@_) { $self->{'basecontext'} = shift; };
  226         675  
64 340         936 return $self->{'basecontext'};
65             }
66              
67             sub captured {
68 13285     13285 1 34542 my ($self, $c) = @_;
69 13285 50       41932 if (defined($c)) {
70 13285         50971 my $t = $self->engine->stackTop;
71 13285         29263 my $n = 0;
72 13285         29542 my @o = ();
73 13285         46757 while (defined($c->[$n])) {
74 1328         3965 push @o, $c->[$n];
75 1328         3947 $n ++;
76             }
77 13285 100       43338 if (@o) {
78 1204         6650 $t->[2] = \@o;
79             }
80             };
81             }
82              
83             sub capturedGet {
84 5384     5384 1 21867 my ($self, $num) = @_;
85 5384         20392 my $s = $self->engine->{stack};
86 5384 50       14778 if (defined($s->[1])) {
87 5384         11147 my $c = $s->[1]->[2];
88 5384         13726 $num --;
89 5384 50       12796 if (defined($c)) {
90 5384 50       13085 if (defined($c->[$num])) {
91 5384         12212 my $r = $c->[$num];
92 5384         16543 return $r;
93             } else {
94 1         52 warn "capture number $num not defined";
95             }
96             } else {
97 1         10 warn "dynamic substitution is called for but nothing to substitute\n";
98 1         3 return undef;
99             }
100             } else {
101 1         66 warn "no parent context to take captures from";
102             }
103             }
104              
105             #sub captured {
106             # my $self = shift;
107             # if (@_) {
108             # $self->{'captured'} = shift;
109             ## print Dumper($self->{'captured'});
110             # };
111             # return $self->{'captured'}
112             ## my ($self, $c) = @_;
113             ## if (defined($c)) {
114             ## my $t = $self->engine->stackTop;
115             ## my $n = 0;
116             ## my @o = ();
117             ## while (defined($c->[$n])) {
118             ## push @o, $c->[$n];
119             ## $n ++;
120             ## }
121             ## if (@o) {
122             ## $t->[2] = \@o;
123             ## }
124             ## };
125             #}
126             #
127             #sub capturedGet {
128             # my ($self, $num) = @_;
129             # my $s = $self->captured;
130             # if (defined $s) {
131             # $num --;
132             # if (defined($s->[$num])) {
133             # return $s->[$num];
134             # } else {
135             # $self->logwarning("capture number $num not defined");
136             # }
137             # } else {
138             # $self->logwarning("dynamic substitution is called for but nothing to substitute");
139             # return undef;
140             # }
141             #}
142              
143             sub capturedParse {
144 5384     5384 1 15020 my ($self, $string, $mode) = @_;
145 5384         11344 my $s = '';
146 5384 100       14796 if (defined($mode)) {
147 49 50       225 if ($string =~ s/^(\d)//) {
148 49         132 $s = $self->capturedGet($1);
149 49 50       220 if ($string ne '') {
150 1         9 $self->logwarning("character class is longer then 1 character, ignoring the rest");
151             }
152             }
153             } else {
154 5336         17760 while ($string ne '') {
155 15939 100       64420 if ($string =~ s/^([^\%]*)\%(\d)//) {
156 5336         18985 my $r = $self->capturedGet($2);
157 5336 50       14772 if ($r ne '') {
158 5336         25991 $s = $s . $1 . $r
159             } else {
160 1         10 $s = $s . $1 . '%' . $2;
161 1         4 $self->logwarning("target is an empty string");
162             }
163             } else {
164 10604         32375 $string =~ s/^(.)//;
165 10604         34145 $s = "$s$1";
166             }
167             }
168             }
169 5384         16179 return $s;
170             }
171              
172             sub column {
173 287     287 1 772 my $self = shift;
174 287         1653 return length($self->{linesegment});
175             }
176              
177             sub contextdata {
178 226     226 1 582 my $self = shift;
179 226 50       856 if (@_) { $self->{'contextdata'} = shift; };
  226         645  
180 226         639 return $self->{'contextdata'};
181             }
182              
183             sub contextInfo {
184 654278     654278 1 1463124 my ($self, $context, $item) = @_;
185 654278 50       1654942 if (exists $self->{contextdata}->{$context}) {
186 654278         1318380 my $c = $self->{contextdata}->{$context};
187 654278 100       1629901 if (exists $c->{$item}) {
188 483842         1366867 return $c->{$item}
189             } else {
190 170437         494562 return undef;
191             }
192             } else {
193 1         35 $self->logwarning("undefined context '$context'");
194 1         7 return undef;
195             }
196             }
197              
198             sub contextParse {
199 57194     57194 1 153445 my ($self, $plug, $context) = @_;
200 57194 100       344163 if ($context =~ /^#pop/i) {
    100          
    100          
201 7770         49354 while ($context =~ s/#pop//i) {
202 9766         32307 $self->stackPull;
203             }
204             } elsif ($context =~ /^#stay/i) {
205             #don't do anything
206             } elsif ($context =~ /^##(.+)/) {
207 7         56 my $new = $self->pluginGet($1);
208 7         44 $self->stackPush([$new, $new->{basecontext}]);
209             } else {
210 10020         41921 $self->stackPush([$plug, $context]);
211             }
212             }
213              
214             sub debug {
215 1     1 0 32 my $self = shift;
216 1 0       7 if (@_) { $self->{'debug'} = shift; };
  1         2  
217 1         30 return $self->{'debug'};
218             }
219              
220             sub debugTest {
221 1     1 0 10 my $self = shift;
222 1 0       3 if (@_) { $self->{'debugtest'} = shift; };
  1         80  
223 1         8 return $self->{'debugtest'};
224             }
225              
226             sub deliminators {
227 226     226 1 474 my $self = shift;
228 226 50       746 if (@_) { $self->{'deliminators'} = shift; };
  226         535  
229 226         650 return $self->{'deliminators'};
230             }
231              
232             sub engine {
233 234106     234106 1 447162 my $self = shift;
234 234106 100       626861 if (@_) { $self->{'engine'} = shift; };
  240         1164  
235 234106         687936 return $self->{'engine'};
236             }
237              
238              
239             sub firstnonspace {
240 238     238 1 710 my ($self, $string) = @_;
241 238         785 my $line = $self->{linesegment};
242 238 100 100     2542 if (($line =~ /^\s*$/) and ($string =~ /^[^\s]/)) {
243 197         890 return 1
244             }
245 42         199 return ''
246             }
247              
248             sub formatTable {
249 56233     56233 1 99844 my $self = shift;
250 56233 50       132487 if (@_) { $self->{'format_table'} = shift; };
  1         3  
251 56233         122414 return $self->{'format_table'};
252             }
253              
254             sub highlight {
255 140     140 1 627 my ($self, $text) = @_;
256 140         903 $self->snippet('');
257 140         371 my $out = $self->{out};
258 140         458 @$out = ();
259 140         620 while ($text ne '') {
260 215530         600416 my $top = $self->stackTop;
261 215530 100       495728 if (defined($top)) {
262 215524         542162 my ($plug, $context) = @$top;
263 215524 100       624309 if ($text =~ s/^(\n)//) {
264 11829         53875 $self->snippetForce;
265 11829         42724 my $e = $plug->contextInfo($context, 'lineending');
266 11829 100       35357 if (defined($e)) {
267 1646         5167 $self->contextParse($plug, $e)
268             }
269 11829         40289 my $attr = $plug->{attributes}->{$plug->contextInfo($context, 'attribute')};
270 11829         46975 $self->snippetParse($1, $attr);
271 11829         35491 $self->snippetForce;
272 11829         26920 $self->{linesegment} = '';
273 11829         33506 my $b = $plug->contextInfo($context, 'linebeginning');
274 11829 50       57343 if (defined($b)) {
275 1         2 $self->contextParse($plug, $b)
276             }
277             } else {
278 203696         542220 my $sub = $plug->contextInfo($context, 'callback');
279 203696         685266 my $result = &$sub($plug, \$text);
280 203696 100       660929 unless($result) {
281 149929         495420 my $f = $plug->contextInfo($context, 'fallthrough');
282 149929 100       348005 if (defined($f)) {
283 1504         5456 $self->contextParse($plug, $f);
284             } else {
285 148426         1104656 $text =~ s/^(.)//;
286 148426         486410 my $attr = $plug->{attributes}->{$plug->contextInfo($context, 'attribute')};
287 148426         474277 $self->snippetParse($1, $attr);
288             }
289             }
290             }
291             } else {
292 7         69 push @$out, length($text), 'Normal';
293 7         33 $text = '';
294             }
295             }
296 140         695 $self->snippetForce;
297 140         57869 return @$out;
298             }
299              
300             sub highlightText {
301 140     140 1 128051 my ($self, $text) = @_;
302 140         1749 my $res = '';
303 140         932 my @hl = $self->highlight($text);
304 140         1134 while (@hl) {
305 56233         108871 my $f = shift @hl;
306 56233         107495 my $t = shift @hl;
307 56233 50       141492 unless (defined($t)) { $t = 'Normal' }
  1         3  
308 56233         112339 my $s = $self->{substitutions};
309 56233         91072 my $rr = '';
310 56233         132136 while ($f ne '') {
311 324916         578325 my $k = substr($f , 0, 1);
312 324916         587816 $f = substr($f, 1, length($f) -1);
313 324916 100       645216 if (exists $s->{$k}) {
314 9735         31679 $rr = $rr . $s->{$k}
315             } else {
316 315181         730174 $rr = $rr . $k;
317             }
318             }
319 56232         132741 my $rt = $self->formatTable;
320 56232 50       149618 if (exists $rt->{$t}) {
321 56232         105338 my $o = $rt->{$t};
322 56232         176904 $res = $res . $o->[0] . $rr . $o->[1];
323             } else {
324 0         0 $res = $res . $rr;
325 0         0 $self->logwarning("undefined format tag '$t'");
326             }
327             }
328 139         15666 return $res;
329             }
330              
331             sub includePlugin {
332 17033     17034 1 41653 my ($self, $language, $text) = @_;
333 17033         35402 my $eng = $self->{engine};
334 17033         51842 my $plug = $eng->pluginGet($language);
335 17033 50       47967 if (defined($plug)) {
336 17033         41400 my $context = $plug->{basecontext};
337 17033         43901 my $call = $plug->contextInfo($context, 'callback');
338 17033 50       37317 if (defined($call)) {
339 17033         58234 return &$call($plug, $text);
340             } else {
341 0         0 $self->logwarning("cannot find callback for context '$context'");
342             }
343             }
344 0         0 return 0;
345             }
346              
347             sub includeRules {
348 80046     80047 1 205778 my ($self, $context, $text) = @_;
349 80046         223616 my $call = $self->contextInfo($context, 'callback');
350 80046 50       193138 if (defined($call)) {
351 80046         267930 return &$call($self, $text);
352             } else {
353 0         0 $self->logwarning("cannot find callback for context '$context'");
354             }
355 0         0 return 0;
356             }
357              
358             sub initialize {
359 451     452 0 879 my $self = shift;
360 451 100       1207 if ($self->engine eq $self) {
361 273         1880 $self->stack([[$self, $self->{basecontext}]]);
362             }
363             }
364              
365             sub keywordscase {
366 225     226 1 517 my $self = shift;
367 225 50       783 if (@_) { $self->{'keywordscase'} = shift; }
  225         491  
368 225         562 return $self->{'keywordscase'}
369             }
370              
371             sub languagePlug {
372 22     23 0 71 my ($cw, $name) = @_;
373 22         324 my %numb = (
374             '1' => 'One',
375             '2' => 'Two',
376             '3' => 'Three',
377             '4' => 'Four',
378             '5' => 'Five',
379             '6' => 'Six',
380             '7' => 'Seven',
381             '8' => 'Eight',
382             '9' => 'Nine',
383             '0' => 'Zero',
384             );
385 22 50       135 if ($name =~ s/^(\d)//) {
386 0         0 $name = $numb{$1} . $name;
387             }
388 22         64 $name =~ s/\.//;
389 22         56 $name =~ s/\+/plus/g;
390 22         48 $name =~ s/\-/minus/g;
391 22         54 $name =~ s/#/dash/g;
392 22         63 $name =~ s/[^0-9a-zA-Z]/_/g;
393 22         64 $name =~ s/__/_/g;
394 22         57 $name =~ s/_$//;
395 22         68 $name = ucfirst($name);
396 22         111 return $name;
397             }
398              
399             sub lastchar {
400 764840     764841 1 1402595 my $self = shift;
401 764840         1499017 my $l = $self->{linesegment};
402 764840 100       1858778 if ($l eq '') { return "\n" } #last character was a newline
  18724         50274  
403 746116         4263471 return substr($l, length($l) - 1, 1);
404             }
405              
406             sub lastcharDeliminator {
407 508993     508994 1 918687 my $self = shift;
408 508993         954311 my $deliminators = '\s|\~|\!|\%|\^|\&|\*|\+|\(|\)|-|=|\{|\}|\[|\]|:|;|<|>|,|\\|\||\.|\?|\/';
409 508993 100 100     1294400 if ($self->linestart or ($self->lastchar =~ /$deliminators/)) {
410 272041         2102121 return 1;
411             }
412 236952         852687 return '';
413             }
414              
415             sub linesegment {
416 801722     801723 1 1378242 my $self = shift;
417 801722 100       1971592 if (@_) { $self->{'linesegment'} = shift; };
  9         26  
418 801722         2586604 return $self->{'linesegment'};
419             }
420              
421             sub linestart {
422 801713     801714 1 1395952 my $self = shift;
423 801713 100       1756265 if ($self->linesegment eq '') {
424 40419         143909 return 1
425             }
426 761294         2598777 return '';
427             }
428              
429             sub lists {
430 0     1 1 0 my $self = shift;
431 0 0       0 if (@_) { $self->{'lists'} = shift; }
  0         0  
432 0         0 return $self->{'lists'}
433             }
434              
435             sub out {
436 116     117 1 225 my $self = shift;
437 116 50       317 if (@_) { $self->{'out'} = shift; }
  116         13389  
438 116         352 return $self->{'out'};
439             }
440              
441             sub listAdd {
442 695     696 1 1349 my $self = shift;
443 695         1241 my $listname = shift;
444 695         1289 my $lst = $self->{lists};
445 695 100       1579 if (@_) {
446 694         18878 my @l = reverse sort @_;
447 694         2733 $lst->{$listname} = \@l;
448             } else {
449 1         4 $lst->{$listname} = [];
450             }
451             }
452              
453             sub logwarning {
454 2     3 0 6 my ($self, $warning) = @_;
455 2         11 my $top = $self->engine->stackTop;
456 2 50       7 if (defined $top) {
457 0         0 my $lang = $top->[0]->language;
458 0         0 my $context = $top->[1];
459 0         0 $warning = "$warning\n Language => $lang, Context => $context\n";
460             } else {
461 2         17 $warning = "$warning\n STACK IS EMPTY: PANIC\n"
462             }
463 2         42 cluck($warning);
464             }
465              
466             sub parseResult {
467 54138     54139 1 234536 my ($self, $text, $string, $lahead, $column, $fnspace, $context, $attr) = @_;
468 54138         152276 my $eng = $self->engine;
469 54138 100       147115 if ($fnspace) {
470 237 100       1187 unless ($eng->firstnonspace($$text)) {
471 41         245 return ''
472             }
473             }
474 54097 100       139339 if (defined($column)) {
475 286 100       1404 if ($column ne $eng->column) {
476 52         303 return '';
477             }
478             }
479 54045 100       152262 unless ($lahead) {
480 52775         306507 $$text = substr($$text, length($string));
481 52775         110670 my $r;
482 52775 100       122624 unless (defined($attr)) {
483 19666         49027 my $t = $eng->stackTop;
484 19666         55430 my ($plug, $ctext) = @$t;
485 19666         61624 $r = $plug->{attributes}->{$plug->contextInfo($ctext, 'attribute')};
486             } else {
487 33109         102868 $r = $self->{attributes}->{$attr};
488             }
489 52775         163045 $eng->snippetParse($string, $r);
490             }
491 54045         194198 $eng->contextParse($self, $context);
492 54045         349456 return 1
493             }
494              
495             sub pluginGet {
496 17155     17156 1 37432 my ($self, $language) = @_;
497 17155         38268 my $plugs = $self->{'plugins'};
498 17155 100       57021 unless (exists($plugs->{$language})) {
499 91         545 my $lang_plug = $self->languagePlug($language);
500 91         214 my $modname = 'Syntax::Highlight::Engine::Kate::';
501 91 100       285 if (defined $lang_plug) {
502 89         242 $modname .= $lang_plug;
503             }
504 91 50       338 unless (defined($modname)) {
505 0         0 $self->logwarning("no valid module found for language '$language'");
506 0         0 return undef;
507             }
508 91         203 my $plug;
509 6     6   6459 eval "use $modname; \$plug = new $modname(engine => \$self);";
  6     5   79  
  6     4   397  
  5     4   2570  
  5     4   21  
  5         239  
  4         2344  
  4         14  
  4         173  
  4         565  
  3         7  
  3         254  
  4         1097  
  3         10  
  3         133  
  91         22514  
510 91 100       370 if (defined($plug)) {
511 89         1378 $plugs->{$language} = $plug;
512             } else {
513 2         25 $self->logwarning("cannot create plugin for language '$language'\n--------------\n$@");
514             }
515             }
516 17155 100       50117 if (exists($plugs->{$language})) {
517 17153         46185 return $plugs->{$language};
518             }
519 2         8 return undef;
520             }
521              
522             sub reset {
523 0     1 1 0 my $self = shift;
524 0         0 $self->stack([[$self, $self->{basecontext}]]);
525 0         0 $self->out([]);
526 0         0 $self->snippet('');
527             }
528              
529             sub snippet {
530 120700     120701 1 223184 my $self = shift;
531 120700 100       289875 if (@_) { $self->{'snippet'} = shift; }
  56481         125791  
532 120700         317603 return $self->{'snippet'};
533             }
534              
535             sub snippetAppend {
536 213028     213029 1 567453 my ($self, $ch) = @_;
537              
538 213028 100       544790 return if not defined $ch;
539 213014         496867 $self->{'snippet'} = $self->{'snippet'} . $ch;
540 213014 50       551640 if ($ch ne '') {
541 213014         458081 $self->{linesegment} = $self->{linesegment} . $ch;
542             }
543 213014         717929 return;
544             }
545              
546             sub snippetAttribute {
547 0     1 1 0 my $self = shift;
548 0 0       0 if (@_) { $self->{'snippetattribute'} = shift; }
  0         0  
549 0         0 return $self->{'snippetattribute'};
550             }
551              
552             sub snippetForce {
553 64219     64220 1 133850 my $self = shift;
554 64219         167528 my $parse = $self->snippet;
555 64219 100       179741 if ($parse ne '') {
556 56226         128126 my $out = $self->{'out'};
557 56226         182211 push(@$out, $parse, $self->{snippetattribute});
558 56226         132944 $self->snippet('');
559             }
560             }
561              
562             sub snippetParse {
563 213028     213029 1 410846 my $self = shift;
564 213028         562311 my $snip = shift;
565 213028         409712 my $attr = shift;
566 213028 100 100     1145819 if ((defined $attr) and ($attr ne $self->{snippetattribute})) {
567 40424         153910 $self->snippetForce;
568 40424         84409 $self->{snippetattribute} = $attr;
569             }
570 213028         616934 $self->snippetAppend($snip);
571             }
572              
573             sub stack {
574 389     390 1 914 my $self = shift;
575 389 50       8311 if (@_) { $self->{'stack'} = shift; }
  389         1632  
576 389         1068 return $self->{'stack'};
577             }
578              
579             sub stackPush {
580 10025     10026 1 24318 my ($self, $val) = @_;
581 10025         21140 my $stack = $self->{stack};
582 10025         30927 unshift(@$stack, $val);
583             }
584              
585             sub stackPull {
586 9765     9766 1 25444 my ($self, $val) = @_;
587 9765         22451 my $stack = $self->{stack};
588 9765         49169 return shift(@$stack);
589             }
590              
591             sub stackTop {
592 248481     248482 1 523371 my $self = shift;
593 248481         632470 return $self->{stack}->[0];
594             }
595              
596             sub stateCompare {
597 0     1 1 0 my ($self, $state) = @_;
598 0         0 my $h = [ $self->stateGet ];
599 0         0 my $equal = 0;
600 0 0       0 if (Dumper($h) eq Dumper($state)) { $equal = 1 };
  0         0  
601 0         0 return $equal;
602             }
603              
604             sub stateGet {
605 0     1 1 0 my $self = shift;
606 0         0 my $s = $self->{stack};
607 0         0 return @$s;
608             }
609              
610             sub stateSet {
611 0     1 1 0 my $self = shift;
612 0         0 my $s = $self->{stack};
613 0         0 @$s = (@_);
614             }
615              
616             sub substitutions {
617 0     1 1 0 my $self = shift;
618 0 0       0 if (@_) { $self->{'substitutions'} = shift; }
  0         0  
619 0         0 return $self->{'substitutions'};
620             }
621              
622             sub testAnyChar {
623 37571     37572 1 82348 my $self = shift;
624 37571         64193 my $text = shift;
625 37571         68199 my $string = shift;
626 37571         75070 my $insensitive = shift;
627 37571         110911 my $test = substr($$text, 0, 1);
628 37571         72934 my $bck = $test;
629 37571 50       94298 if ($insensitive) {
630 0         0 $string = lc($string);
631 0         0 $test = lc($test);
632             }
633 37571 100       120928 if (index($string, $test) > -1) {
634 5179         20343 return $self->parseResult($text, $bck, @_);
635             }
636 32392         123390 return ''
637             }
638              
639             sub testDetectChar {
640 333362     333363 1 613247 my $self = shift;
641 333362         574832 my $text = shift;
642 333362         595206 my $char = shift;
643 333362         552978 my $insensitive = shift;
644 333362         615344 my $dyn = shift;
645 333362 100       811623 if ($dyn) {
646 48         159 $char = $self->capturedParse($char, 1);
647             }
648 333362         698485 my $test = substr($$text, 0, 1);
649 333362         591374 my $bck = $test;
650 333362 50       759865 if ($insensitive) {
651 0         0 $char = lc($char);
652 0         0 $test = lc($test);
653             }
654 333362 100       835507 if ($char eq $test) {
655 9591         35733 return $self->parseResult($text, $bck, @_);
656             }
657 323771         1071147 return ''
658             }
659              
660             sub testDetect2Chars {
661 221495     221496 1 412036 my $self = shift;
662 221495         369829 my $text = shift;
663 221495         388130 my $char = shift;
664 221495         402412 my $char1 = shift;
665 221495         388649 my $insensitive = shift;
666 221495         384239 my $dyn = shift;
667 221495 50       517780 if ($dyn) {
668 0         0 $char = $self->capturedParse($char, 1);
669 0         0 $char1 = $self->capturedParse($char1, 1);
670             }
671 221495         431496 my $string = $char . $char1;
672 221495         475264 my $test = substr($$text, 0, 2);
673 221495         387022 my $bck = $test;
674 221495 50       504015 if ($insensitive) {
675 0         0 $string = lc($string);
676 0         0 $test = lc($test);
677             }
678 221495 100       540025 if ($string eq $test) {
679 1263         5311 return $self->parseResult($text, $bck, @_);
680             }
681 220232         796151 return ''
682             }
683              
684             sub testDetectIdentifier {
685 16809     16810 1 31764 my $self = shift;
686 16809         29438 my $text = shift;
687 16809 100       82192 if ($$text =~ /^([a-zA-Z_][a-zA-Z0-9_]+)/) {
688 7537         25254 return $self->parseResult($text, $1, @_);
689             }
690 9272         29496 return ''
691             }
692              
693             sub testDetectSpaces {
694 33860     33861 1 92219 my $self = shift;
695 33860         64135 my $text = shift;
696 33860 100       150258 if ($$text =~ /^([\040\t]+)/) {
697 11911         39629 return $self->parseResult($text, $1, @_);
698             }
699 21949         69350 return ''
700             }
701              
702             sub testFloat {
703 49443     49444 1 97219 my $self = shift;
704 49443         85949 my $text = shift;
705 49443 100       164671 if ($self->engine->lastcharDeliminator) {
706 25619 100       128085 if ($$text =~ /^((?=\.?\d)\d*(?:\.\d*)?(?:[Ee][+-]?\d+)?)/) {
707 1912         8730 return $self->parseResult($text, $1, @_);
708             }
709             }
710 47531         172600 return ''
711             }
712              
713             sub testHlCChar {
714 22740     22741 1 45372 my $self = shift;
715 22740         42834 my $text = shift;
716 22740 100       79502 if ($$text =~ /^('.')/) {
717 26         110 return $self->parseResult($text, $1, @_);
718             }
719 22714         81805 return ''
720             }
721              
722             sub testHlCHex {
723 31141     31142 1 66606 my $self = shift;
724 31141         53230 my $text = shift;
725 31141 100       79068 if ($self->engine->lastcharDeliminator) {
726 15995 100       57890 if ($$text =~ /^(0x[0-9a-fA-F]+)/) {
727 8         66 return $self->parseResult($text, $1, @_);
728             }
729             }
730 31133         116279 return ''
731             }
732              
733             sub testHlCOct {
734 25303     25304 1 46472 my $self = shift;
735 25303         46916 my $text = shift;
736 25303 100       65927 if ($self->engine->lastcharDeliminator) {
737 13765 50       44838 if ($$text =~ /^(0[0-7]+)/) {
738 0         0 return $self->parseResult($text, $1, @_);
739             }
740             }
741 25303         88543 return ''
742             }
743              
744             sub testHlCStringChar {
745 5020     5021 1 9003 my $self = shift;
746 5020         7790 my $text = shift;
747 5020 100       18116 if ($$text =~ /^(\\[a|b|e|f|n|r|t|v|'|"|\?])/) {
748 34         168 return $self->parseResult($text, $1, @_);
749             }
750 4986 50       14055 if ($$text =~ /^(\\x[0-9a-fA-F][0-9a-fA-F]?)/) {
751 0         0 return $self->parseResult($text, $1, @_);
752             }
753 4986 50       14986 if ($$text =~ /^(\\[0-7][0-7]?[0-7]?)/) {
754 0         0 return $self->parseResult($text, $1, @_);
755             }
756 4986         15207 return ''
757             }
758              
759             sub testInt {
760 54721     54722 1 123205 my $self = shift;
761 54721         100593 my $text = shift;
762 54721 100       148052 if ($self->engine->lastcharDeliminator) {
763 26837 100       118477 if ($$text =~ /^([+-]?\d+)/) {
764 314         1652 return $self->parseResult($text, $1, @_);
765             }
766             }
767 54407         205300 return ''
768             }
769              
770             sub testKeyword {
771 348385     348386 1 642597 my $self = shift;
772 348385         613494 my $text = shift;
773 348385         626993 my $list = shift;
774 348385         740708 my $eng = $self->{engine};
775 348385         686805 my $deliminators = $self->{deliminators};
776 348385 100 100     842187 if (($eng->lastcharDeliminator) and ($$text =~ /^([^$deliminators]+)/)) {
777 73262         213685 my $match = $1;
778 73262         210399 my $l = $self->{lists}->{$list};
779 73262 50       172629 if (defined($l)) {
780 73262         1100655 my @list = @$l;
781 73262         141628 my @rl = ();
782 73262 100       194910 unless ($self->{keywordscase}) {
783 67024         171934 @rl = grep { (lc($match) eq lc($_)) } @list;
  6124282         12084100  
784             } else {
785 6238         15469 @rl = grep { ($match eq $_) } @list;
  111076         222579  
786             }
787 73262 100       466276 if (@rl) {
788 5832         34679 return $self->parseResult($text, $match, @_);
789             }
790             } else {
791 0         0 $self->logwarning("list '$list' is not defined, failing test");
792             }
793             }
794 342553         1329220 return ''
795             }
796              
797             sub testLineContinue {
798 6210     6211 1 11814 my $self = shift;
799 6210         11552 my $text = shift;
800 6210         10845 my $lahead = shift;
801 6210 50       14636 if ($lahead) {
802 0 0       0 if ($$text =~ /^\\\n/) {
803 0         0 $self->parseResult($text, "\\", $lahead, @_);
804 0         0 return 1;
805             }
806             } else {
807 6210 100       19599 if ($$text =~ s/^(\\)(\n)/$2/) {
808 14         77 return $self->parseResult($text, "\\", $lahead, @_);
809             }
810             }
811 6196         22849 return ''
812             }
813              
814             sub testRangeDetect {
815 15468     15468 1 31001 my $self = shift;
816 15468         34249 my $text = shift;
817 15468         27537 my $char = shift;
818 15468         25765 my $char1 = shift;
819 15468         25208 my $insensitive = shift;
820 15468         33711 my $string = "$char\[^$char1\]+$char1";
821 15468         43940 return $self->testRegExpr($text, $string, $insensitive, 0, @_);
822             }
823              
824             sub testRegExpr {
825 1245760     1245760 1 2317456 my $self = shift;
826 1245760         2210730 my $text = shift;
827 1245760         2295662 my $reg = shift;
828 1245760         2084514 my $insensitive = shift;
829 1245760         2093682 my $dynamic = shift;
830 1245760 100       2880320 if ($dynamic) {
831 5335         17399 $reg = $self->capturedParse($reg);
832             }
833 1245760         2530464 my $eng = $self->{engine};
834 1245760 100       4986627 if ($reg =~ s/^\^//) {
    100          
835 292720 100       691610 unless ($eng->linestart) {
836 282288         1050661 return '';
837             }
838             } elsif ($reg =~ s/^\\(b)//i) {
839 285834         756342 my $lastchar = $eng->lastchar;
840 285834 100       857233 if ($1 eq 'b') {
841 285152 100       917177 if ($lastchar =~ /\w/) { return '' }
  125727         480808  
842             } else {
843 682 100       2890 if ($lastchar =~ /\W/) { return '' }
  308         1401  
844             }
845             }
846 837437         2083734 $reg = "^($reg)";
847 837437         1564256 my $sample = $$text;
848              
849             # emergency measurements to avoid exception (szabgab)
850 837437         1549860 $reg = eval { qr/$reg/ };
  837437         31567306  
851 837437 50       2825490 if ($@) {
852 0         0 warn $@;
853 0         0 return '';
854             }
855 837437         1408189 my $match;
856 837437 100       1886238 if ($insensitive) {
857 122076 100       793683 if ($sample =~ /$reg/i) {
858 158         527 $match = $1;
859 158 50       659 if ($#-) {
860 8     8   1135 no strict 'refs';
  8         18  
  8         814  
861 158         694 my @cap = map {$$_} 2 .. $#-;
  84         570  
862 158         923 $self->captured(\@cap)
863             }
864             }
865             } else {
866 715361 100       4549700 if ($sample =~ /$reg/) {
867 13126         46707 $match = $1;
868 13126 50       49747 if ($#-) {
869 8     8   58 no strict 'refs';
  8         27  
  8         2076  
870 13126         50780 my @cap = map {$$_} 2 .. $#-;
  1303         9725  
871 13126         56158 $self->captured(\@cap);
872             }
873             }
874             }
875 837437 100 100     2425779 if ((defined($match)) and ($match ne '')) {
876 9947         39527 return $self->parseResult($text, $match, @_);
877             }
878 827490         3906566 return ''
879             }
880              
881             sub testStringDetect {
882 1677490     1677490 1 2960881 my $self = shift;
883 1677490         2721718 my $text = shift;
884 1677490         2835183 my $string = shift;
885 1677490         2758500 my $insensitive = shift;
886 1677490         2779554 my $dynamic = shift;
887 1677490 50       3819304 if ($dynamic) {
888 0         0 $string = $self->capturedParse($string);
889             }
890 1677490         3259408 my $test = substr($$text, 0, length($string));
891 1677490         2792304 my $bck = $test;
892 1677490 100       3736721 if ($insensitive) {
893 3672         7789 $string = lc($string);
894 3672         6771 $test = lc($test);
895             }
896 1677490 100       3775632 if ($string eq $test) {
897 570         2415 return $self->parseResult($text, $bck, @_);
898             }
899 1676920         5536792 return ''
900             }
901              
902              
903             1;
904              
905             __END__