File Coverage

blib/lib/Syntax/Highlight/Engine/Kate/Template.pm
Criterion Covered Total %
statement 528 578 91.3
branch 192 234 82.0
condition 15 18 83.3
subroutine 73 73 100.0
pod 57 63 90.4
total 865 966 89.5


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.12';
8              
9 7     7   54 use strict;
  7         22  
  7         203  
10 7     7   51 use Carp qw(cluck);
  7         14  
  7         298  
11 7     7   50 use Data::Dumper;
  7         14  
  7         23614  
12              
13             #my $regchars = '\\^.$|()[]*+?';
14              
15             sub new {
16 232     232 0 669 my $proto = shift;
17 232   33     1008 my $class = ref($proto) || $proto;
18 232         804 my %args = (@_);
19              
20 232         622 my $debug = delete $args{'debug'};
21 232 50       748 unless (defined($debug)) { $debug = 0 };
  232         463  
22 232         485 my $substitutions = delete $args{'substitutions'};
23 232 100       656 unless (defined($substitutions)) { $substitutions = {} };
  101         275  
24 232         506 my $formattable = delete $args{'format_table'};
25 232 100       1144 unless (defined($formattable)) { $formattable = {} };
  95         419  
26 232         579 my $engine = delete $args{'engine'};
27              
28 232         479 my $self = {};
29             $self->{'attributes'} = {},
30 232         926 $self->{'captured'} = [];
31 232         551 $self->{'contextdata'} = {};
32 232         602 $self->{'basecontext'} = '';
33 232         730 $self->{'debug'} = $debug;
34 232         553 $self->{'deliminators'} = '';
35 232         537 $self->{'engine'} = '';
36 232         729 $self->{'format_table'} = $formattable;
37 232         543 $self->{'keywordcase'} = 1;
38 232         555 $self->{'lastchar'} = '';
39 232         570 $self->{'linesegment'} = '';
40 232         493 $self->{'lists'} = {};
41 232         508 $self->{'linestart'} = 1;
42 232         581 $self->{'out'} = [];
43 232         530 $self->{'plugins'} = {};
44 232         753 $self->{'snippet'} = '';
45 232         549 $self->{'snippetattribute'} = '';
46 232         541 $self->{'stack'} = [];
47 232         455 $self->{'substitutions'} = $substitutions;
48 232         482 bless ($self, $class);
49 232 100       707 unless (defined $engine) { $engine = $self };
  144         341  
50 232         1320 $self->engine($engine);
51 232         1207 $self->initialize;
52 232         853 return $self;
53             }
54              
55             sub attributes {
56 220716     220716 1 349882 my $self = shift;
57 220716 100       440148 if (@_) { $self->{'attributes'} = shift; };
  219         577  
58 220716         591177 return $self->{'attributes'};
59             }
60              
61             sub basecontext {
62 23505     23505 1 37312 my $self = shift;
63 23505 100       47273 if (@_) { $self->{'basecontext'} = shift; };
  219         498  
64 23505         45856 return $self->{'basecontext'};
65             }
66              
67             sub captured {
68 1220     1220 1 4536 my ($self, $c) = @_;
69 1220 50       4524 if (defined($c)) {
70 1220         3733 my $t = $self->engine->stackTop;
71 1220         2764 my $n = 0;
72 1220         3083 my @o = ();
73 1220         5068 while (defined($c->[$n])) {
74 1320         3870 push @o, $c->[$n];
75 1320         3623 $n ++;
76             }
77 1220 100       4044 if (@o) {
78 1196         4607 $t->[2] = \@o;
79             }
80             };
81             }
82              
83             sub capturedGet {
84 5334     5334 1 13537 my ($self, $num) = @_;
85 5334         10962 my $s = $self->engine->stack;
86 5334 50       10495 if (defined($s->[1])) {
87 5334         8146 my $c = $s->[1]->[2];
88 5334         9935 $num --;
89 5334 50       8685 if (defined($c)) {
90 5334 50       8820 if (defined($c->[$num])) {
91 5334         8074 my $r = $c->[$num];
92 5334         10681 return $r;
93             } else {
94 1         39 warn "capture number $num not defined";
95             }
96             } else {
97 1         7 warn "dynamic substitution is called for but nothing to substitute\n";
98 1         2 return undef;
99             }
100             } else {
101 1         35 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 5334     5334 1 9329 my ($self, $string, $mode) = @_;
145 5334         7288 my $s = '';
146 5334 100       9432 if (defined($mode)) {
147 35 50       139 if ($string =~ s/^(\d)//) {
148 35         71 $s = $self->capturedGet($1);
149 35 50       108 if ($string ne '') {
150 1         10 $self->logwarning("character class is longer then 1 character, ignoring the rest");
151             }
152             }
153             } else {
154 5300         9938 while ($string ne '') {
155 15739 100       42023 if ($string =~ s/^([^\%]*)\%(\d)//) {
156 5300         10806 my $r = $self->capturedGet($2);
157 5300 50       9612 if ($r ne '') {
158 5300         15945 $s = $s . $1 . $r
159             } else {
160 1         6 $s = $s . $1 . '%' . $2;
161 1         6 $self->logwarning("target is an empty string");
162             }
163             } else {
164 10440         20415 $string =~ s/^(.)//;
165 10440         21876 $s = "$s$1";
166             }
167             }
168             }
169 5334         10442 return $s;
170             }
171              
172             sub column {
173 285     285 1 527 my $self = shift;
174 285         680 return length($self->linesegment);
175             }
176              
177             sub contextdata {
178 1392317     1392317 1 1917599 my $self = shift;
179 1392317 100       2411826 if (@_) { $self->{'contextdata'} = shift; };
  219         569  
180 1392317         2749306 return $self->{'contextdata'};
181             }
182              
183             sub contextInfo {
184 696050     696050 1 1254848 my ($self, $context, $item) = @_;
185 696050 50       1234072 if (exists $self->contextdata->{$context}) {
186 696050         1161222 my $c = $self->contextdata->{$context};
187 696050 100       1343743 if (exists $c->{$item}) {
188 506732         1123651 return $c->{$item}
189             } else {
190 189319         409699 return undef;
191             }
192             } else {
193 1         27 $self->logwarning("undefined context '$context'");
194 1         8 return undef;
195             }
196             }
197              
198             sub contextParse {
199 45680     45680 1 98891 my ($self, $plug, $context) = @_;
200 45680 100       217687 if ($context =~ /^#pop/i) {
    100          
    100          
201 7676         39950 while ($context =~ s/#pop//i) {
202 9604         27242 $self->stackPull;
203             }
204             } elsif ($context =~ /^#stay/i) {
205             #don't do anything
206             } elsif ($context =~ /^##(.+)/) {
207 7         61 my $new = $self->pluginGet($1);
208 7         44 $self->stackPush([$new, $new->basecontext]);
209             } else {
210 9847         36490 $self->stackPush([$plug, $context]);
211             }
212             }
213              
214             sub debug {
215 1     1 0 51 my $self = shift;
216 1 0       17 if (@_) { $self->{'debug'} = shift; };
  1         5  
217 1         71 return $self->{'debug'};
218             }
219              
220             sub debugTest {
221 1     1 0 8 my $self = shift;
222 1 0       3 if (@_) { $self->{'debugtest'} = shift; };
  1         41  
223 1         9 return $self->{'debugtest'};
224             }
225              
226             sub deliminators {
227 372782     372782 1 558210 my $self = shift;
228 372782 100       689518 if (@_) { $self->{'deliminators'} = shift; };
  219         527  
229 372782         652548 return $self->{'deliminators'};
230             }
231              
232             sub engine {
233 2319452     2319452 1 3184137 my $self = shift;
234 2319452 100       4130822 if (@_) { $self->{'engine'} = shift; };
  232         975  
235 2319452         4429194 return $self->{'engine'};
236             }
237              
238              
239             sub firstnonspace {
240 235     235 1 681 my ($self, $string) = @_;
241 235         609 my $line = $self->linesegment;
242 235 100 66     1947 if (($line =~ /^\s*$/) and ($string =~ /^[^\s]/)) {
243 197         663 return 1
244             }
245 39         143 return ''
246             }
247              
248             sub formatTable {
249 55848     55848 1 76301 my $self = shift;
250 55848 50       90705 if (@_) { $self->{'format_table'} = shift; };
  1         2  
251 55848         85507 return $self->{'format_table'};
252             }
253              
254             sub highlight {
255 109     109 1 445 my ($self, $text) = @_;
256 109         636 $self->snippet('');
257 109         496 my $out = $self->out;
258 109         358 @$out = ();
259 109         404 while ($text ne '') {
260 222938         471209 my $top = $self->stackTop;
261 222938 100       450593 if (defined($top)) {
262 222932         430871 my ($plug, $context) = @$top;
263 222932 100       518100 if ($text =~ s/^(\n)//) {
264 11829         36979 $self->snippetForce;
265 11829         28969 my $e = $plug->contextInfo($context, 'lineending');
266 11829 100       28025 if (defined($e)) {
267 1644         4160 $self->contextParse($plug, $e)
268             }
269 11829         26543 my $attr = $plug->attributes->{$plug->contextInfo($context, 'attribute')};
270 11829         36185 $self->snippetParse($1, $attr);
271 11829         32728 $self->snippetForce;
272 11829         31303 $self->linesegment('');
273 11829         29370 my $b = $plug->contextInfo($context, 'linebeginning');
274 11829 50       39646 if (defined($b)) {
275 1         7 $self->contextParse($plug, $b)
276             }
277             } else {
278 211104         417579 my $sub = $plug->contextInfo($context, 'callback');
279 211104         621114 my $result = &$sub($plug, \$text);
280 211104 100       513605 unless($result) {
281 168741         409051 my $f = $plug->contextInfo($context, 'fallthrough');
282 168741 100       345330 if (defined($f)) {
283 1436         3520 $self->contextParse($plug, $f);
284             } else {
285 167306         991303 $text =~ s/^(.)//;
286 167306         416064 my $attr = $plug->attributes->{$plug->contextInfo($context, 'attribute')};
287 167306         385353 $self->snippetParse($1, $attr);
288             }
289             }
290             }
291             } else {
292 7         63 push @$out, length($text), 'Normal';
293 7         32 $text = '';
294             }
295             }
296 109         416 $self->snippetForce;
297 109         29416 return @$out;
298             }
299              
300             sub highlightText {
301 109     109 1 59986 my ($self, $text) = @_;
302 109         294 my $res = '';
303 109         680 my @hl = $self->highlight($text);
304 109         824 while (@hl) {
305 55848         95659 my $f = shift @hl;
306 55848         81113 my $t = shift @hl;
307 55848 50       97597 unless (defined($t)) { $t = 'Normal' }
  1         3  
308 55848         93097 my $s = $self->substitutions;
309 55848         77231 my $rr = '';
310 55848         94179 while ($f ne '') {
311 324031         461353 my $k = substr($f , 0, 1);
312 324031         463239 $f = substr($f, 1, length($f) -1);
313 324031 100       491575 if (exists $s->{$k}) {
314 9735         19878 $rr = $rr . $s->{$k}
315             } else {
316 314296         528054 $rr = $rr . $k;
317             }
318             }
319 55847         92837 my $rt = $self->formatTable;
320 55847 50       95466 if (exists $rt->{$t}) {
321 55847         76301 my $o = $rt->{$t};
322 55847         306364 $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 108         6515 return $res;
329             }
330              
331             sub includePlugin {
332 22906     22907 1 44514 my ($self, $language, $text) = @_;
333 22906         43503 my $eng = $self->engine;
334 22906         51045 my $plug = $eng->pluginGet($language);
335 22906 50       49381 if (defined($plug)) {
336 22906         48510 my $context = $plug->basecontext;
337 22906         45449 my $call = $plug->contextInfo($context, 'callback');
338 22906 50       43752 if (defined($call)) {
339 22906         56140 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 81919     81920 1 193878 my ($self, $context, $text) = @_;
349 81919         183760 my $call = $self->contextInfo($context, 'callback');
350 81919 50       189641 if (defined($call)) {
351 81919         216334 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 436     437 0 788 my $self = shift;
360 436 100       929 if ($self->engine eq $self) {
361 260         1030 $self->stack([[$self, $self->basecontext]]);
362             }
363             }
364              
365             sub keywordscase {
366 72502     72503 1 114029 my $self = shift;
367 72502 100       145713 if (@_) { $self->{'keywordcase'} = shift; }
  218         507  
368 72502         156611 return $self->{'keywordscase'}
369             }
370              
371             sub languagePlug {
372 21     22 0 62 my ($cw, $name) = @_;
373 21         206 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 21 50       98 if ($name =~ s/^(\d)//) {
386 0         0 $name = $numb{$1} . $name;
387             }
388 21         56 $name =~ s/\.//;
389 21         50 $name =~ s/\+/plus/g;
390 21         46 $name =~ s/\-/minus/g;
391 21         61 $name =~ s/#/dash/g;
392 21         71 $name =~ s/[^0-9a-zA-Z]/_/g;
393 21         38 $name =~ s/__/_/g;
394 21         56 $name =~ s/_$//;
395 21         78 $name = ucfirst($name);
396 21         83 return $name;
397             }
398              
399             sub lastchar {
400 838555     838556 1 1241542 my $self = shift;
401 838555         1381713 my $l = $self->linesegment;
402 838555 100       1633877 if ($l eq '') { return "\n" } #last character was a newline
  24123         47400  
403 814432         3090319 return substr($l, length($l) - 1, 1);
404             }
405              
406             sub lastcharDeliminator {
407 566120     566121 1 806054 my $self = shift;
408 566120         767999 my $deliminators = '\s|\~|\!|\%|\^|\&|\*|\+|\(|\)|-|=|\{|\}|\[|\]|:|;|<|>|,|\\|\||\.|\?|\/';
409 566120 100 100     953255 if ($self->linestart or ($self->lastchar =~ /$deliminators/)) {
410 310009         1665752 return 1;
411             }
412 256111         668394 return '';
413             }
414              
415             sub linesegment {
416 2151910     2151911 1 2906584 my $self = shift;
417 2151910 100       3784126 if (@_) { $self->{'linesegment'} = shift; };
  232311         370440  
418 2151910         4607654 return $self->{'linesegment'};
419             }
420              
421             sub linestart {
422 860043     860044 1 1220749 my $self = shift;
423 860043 100       1407711 if ($self->linesegment eq '') {
424 48445         126350 return 1
425             }
426 811598         2155134 return '';
427             }
428              
429             sub lists {
430 72954     72955 1 114137 my $self = shift;
431 72954 50       148561 if (@_) { $self->{'lists'} = shift; }
  0         0  
432 72954         167916 return $self->{'lists'}
433             }
434              
435             sub out {
436 224     225 1 428 my $self = shift;
437 224 100       608 if (@_) { $self->{'out'} = shift; }
  116         7036  
438 224         555 return $self->{'out'};
439             }
440              
441             sub listAdd {
442 670     671 1 1139 my $self = shift;
443 670         1051 my $listname = shift;
444 670         1633 my $lst = $self->lists;
445 670 100       1438 if (@_) {
446 669         13319 my @l = reverse sort @_;
447 669         2448 $lst->{$listname} = \@l;
448             } else {
449 1         4 $lst->{$listname} = [];
450             }
451             }
452              
453             sub logwarning {
454 2     3 0 9 my ($self, $warning) = @_;
455 2         11 my $top = $self->engine->stackTop;
456 2 50       8 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         7 $warning = "$warning\n STACK IS EMPTY: PANIC\n"
462             }
463 2         45 cluck($warning);
464             }
465              
466             sub parseResult {
467 42690     42691 1 126792 my ($self, $text, $string, $lahead, $column, $fnspace, $context, $attr) = @_;
468 42690         89476 my $eng = $self->engine;
469 42690 100       94602 if ($fnspace) {
470 234 100       920 unless ($eng->firstnonspace($$text)) {
471 38         179 return ''
472             }
473             }
474 42652 100       99119 if (defined($column)) {
475 284 100       928 if ($column ne $eng->column) {
476 51         202 return '';
477             }
478             }
479 42601 100       88710 unless ($lahead) {
480 41364         194507 $$text = substr($$text, length($string));
481 41364         62618 my $r;
482 41364 100       79258 unless (defined($attr)) {
483 8592         17584 my $t = $eng->stackTop;
484 8592         19921 my ($plug, $ctext) = @$t;
485 8592         18507 $r = $plug->attributes->{$plug->contextInfo($ctext, 'attribute')};
486             } else {
487 32772         82889 $r = $self->attributes->{$attr};
488             }
489 41364         95477 $eng->snippetParse($string, $r);
490             }
491 42601         118928 $eng->contextParse($self, $context);
492 42601         208156 return 1
493             }
494              
495             sub pluginGet {
496 23028     23029 1 42886 my ($self, $language) = @_;
497 23028         36985 my $plugs = $self->{'plugins'};
498 23028 100       50926 unless (exists($plugs->{$language})) {
499 90         419 my $lang_plug = $self->languagePlug($language);
500 90         258 my $modname = 'Syntax::Highlight::Engine::Kate::';
501 90 100       306 if (defined $lang_plug) {
502 88         223 $modname .= $lang_plug;
503             }
504 90 50       259 unless (defined($modname)) {
505 0         0 $self->logwarning("no valid module found for language '$language'");
506 0         0 return undef;
507             }
508 90         224 my $plug;
509 5     5   2122 eval "use $modname; \$plug = new $modname(engine => \$self);";
  5     5   36  
  5     4   190  
  5     4   1848  
  5     4   15  
  5         158  
  4         1405  
  4         14  
  4         146  
  4         265  
  3         6  
  3         79  
  4         523  
  3         8  
  3         106  
  90         17149  
510 90 100       432 if (defined($plug)) {
511 88         302 $plugs->{$language} = $plug;
512             } else {
513 2         53 $self->logwarning("cannot create plugin for language '$language'\n--------------\n$@");
514             }
515             }
516 23028 100       52643 if (exists($plugs->{$language})) {
517 23026         48615 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 119868     119869 1 190009 my $self = shift;
531 119868 100       222282 if (@_) { $self->{'snippet'} = shift; }
  56065         92060  
532 119868         227404 return $self->{'snippet'};
533             }
534              
535             sub snippetAppend {
536 220497     220498 1 406645 my ($self, $ch) = @_;
537              
538 220497 100       437634 return if not defined $ch;
539 220483         468495 $self->{'snippet'} = $self->{'snippet'} . $ch;
540 220483 50       429208 if ($ch ne '') {
541 220483         451516 $self->linesegment($self->linesegment . $ch);
542             }
543 220483         630308 return;
544             }
545              
546             sub snippetAttribute {
547 315674     315675 1 470907 my $self = shift;
548 315674 100       602961 if (@_) { $self->{'snippetattribute'} = shift; }
  40039         67727  
549 315674         920523 return $self->{'snippetattribute'};
550             }
551              
552             sub snippetForce {
553 63803     63804 1 106356 my $self = shift;
554 63803         136066 my $parse = $self->snippet;
555 63803 100       146939 if ($parse ne '') {
556 55841         91475 my $out = $self->{'out'};
557 55841         110097 push(@$out, $parse, $self->snippetAttribute);
558 55841         108597 $self->snippet('');
559             }
560             }
561              
562             sub snippetParse {
563 220497     220498 1 339254 my $self = shift;
564 220497         461836 my $snip = shift;
565 220497         331679 my $attr = shift;
566 220497 100 100     610734 if ((defined $attr) and ($attr ne $self->snippetAttribute)) {
567 40039         99573 $self->snippetForce;
568 40039         73614 $self->snippetAttribute($attr);
569             }
570 220497         504956 $self->snippetAppend($snip);
571             }
572              
573             sub stack {
574 257914     257915 1 364704 my $self = shift;
575 257914 100       503016 if (@_) { $self->{'stack'} = shift; }
  376         1157  
576 257914         544068 return $self->{'stack'};
577             }
578              
579             sub stackPush {
580 9852     9853 1 22688 my ($self, $val) = @_;
581 9852         22637 my $stack = $self->stack;
582 9852         27331 unshift(@$stack, $val);
583             }
584              
585             sub stackPull {
586 9603     9604 1 21860 my ($self, $val) = @_;
587 9603         20176 my $stack = $self->stack;
588 9603         35417 return shift(@$stack);
589             }
590              
591             sub stackTop {
592 232750     232751 1 356544 my $self = shift;
593 232750         439873 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 55847     55848 1 72419 my $self = shift;
618 55847 50       91787 if (@_) { $self->{'substitutions'} = shift; }
  0         0  
619 55847         86980 return $self->{'substitutions'};
620             }
621              
622             sub testAnyChar {
623 40943     40944 1 69613 my $self = shift;
624 40943         66634 my $text = shift;
625 40943         62655 my $string = shift;
626 40943         63892 my $insensitive = shift;
627 40943         83375 my $test = substr($$text, 0, 1);
628 40943         62348 my $bck = $test;
629 40943 50       77417 if ($insensitive) {
630 0         0 $string = lc($string);
631 0         0 $test = lc($test);
632             }
633 40943 100       107713 if (index($string, $test) > -1) {
634 5108         16738 return $self->parseResult($text, $bck, @_);
635             }
636 35835         106237 return ''
637             }
638              
639             sub testDetectChar {
640 385816     385817 1 584132 my $self = shift;
641 385816         517166 my $text = shift;
642 385816         563977 my $char = shift;
643 385816         548142 my $insensitive = shift;
644 385816         512061 my $dyn = shift;
645 385816 100       665999 if ($dyn) {
646 34         63 $char = $self->capturedParse($char, 1);
647             }
648 385816         621545 my $test = substr($$text, 0, 1);
649 385816         519136 my $bck = $test;
650 385816 50       642980 if ($insensitive) {
651 0         0 $char = lc($char);
652 0         0 $test = lc($test);
653             }
654 385816 100       693869 if ($char eq $test) {
655 9535         31265 return $self->parseResult($text, $bck, @_);
656             }
657 376281         946345 return ''
658             }
659              
660             sub testDetect2Chars {
661 236078     236079 1 371350 my $self = shift;
662 236078         314287 my $text = shift;
663 236078         353164 my $char = shift;
664 236078         321487 my $char1 = shift;
665 236078         325051 my $insensitive = shift;
666 236078         327113 my $dyn = shift;
667 236078 50       410187 if ($dyn) {
668 0         0 $char = $self->capturedParse($char, 1);
669 0         0 $char1 = $self->capturedParse($char1, 1);
670             }
671 236078         378265 my $string = $char . $char1;
672 236078         398887 my $test = substr($$text, 0, 2);
673 236078         329245 my $bck = $test;
674 236078 50       418182 if ($insensitive) {
675 0         0 $string = lc($string);
676 0         0 $test = lc($test);
677             }
678 236078 100       436553 if ($string eq $test) {
679 1263         4613 return $self->parseResult($text, $bck, @_);
680             }
681 234815         640842 return ''
682             }
683              
684             sub testDetectIdentifier {
685 29422     29423 1 45710 my $self = shift;
686 29422         41079 my $text = shift;
687 29422 100       83007 if ($$text =~ /^([a-zA-Z_][a-zA-Z0-9_]+)/) {
688 7405         22490 return $self->parseResult($text, $1, @_);
689             }
690 22017         55036 return ''
691             }
692              
693             sub testDetectSpaces {
694 41375     41376 1 69024 my $self = shift;
695 41375         57096 my $text = shift;
696 41375 100       129250 if ($$text =~ /^([\\040|\\t]+)/) {
697 955         3146 return $self->parseResult($text, $1, @_);
698             }
699 40420         101399 return ''
700             }
701              
702             sub testFloat {
703 57829     57830 1 93105 my $self = shift;
704 57829         79997 my $text = shift;
705 57829 100       103433 if ($self->engine->lastcharDeliminator) {
706 31956 100       106009 if ($$text =~ /^((?=\.?\d)\d*(?:\.\d*)?(?:[Ee][+-]?\d+)?)/) {
707 1845         6546 return $self->parseResult($text, $1, @_);
708             }
709             }
710 55984         153844 return ''
711             }
712              
713             sub testHlCChar {
714 24992     24993 1 44380 my $self = shift;
715 24992         35270 my $text = shift;
716 24992 100       60564 if ($$text =~ /^('.')/) {
717 26         113 return $self->parseResult($text, $1, @_);
718             }
719 24966         63341 return ''
720             }
721              
722             sub testHlCHex {
723 39211     39212 1 64384 my $self = shift;
724 39211         53755 my $text = shift;
725 39211 100       66556 if ($self->engine->lastcharDeliminator) {
726 22158 100       51211 if ($$text =~ /^(0x[0-9a-fA-F]+)/) {
727 8         35 return $self->parseResult($text, $1, @_);
728             }
729             }
730 39203         104995 return ''
731             }
732              
733             sub testHlCOct {
734 33373     33374 1 54349 my $self = shift;
735 33373         47815 my $text = shift;
736 33373 100       61304 if ($self->engine->lastcharDeliminator) {
737 19928 50       48682 if ($$text =~ /^(0[0-7]+)/) {
738 0         0 return $self->parseResult($text, $1, @_);
739             }
740             }
741 33373         92371 return ''
742             }
743              
744             sub testHlCStringChar {
745 5020     5021 1 8201 my $self = shift;
746 5020         7978 my $text = shift;
747 5020 100       11557 if ($$text =~ /^(\\[a|b|e|f|n|r|t|v|'|"|\?])/) {
748 34         143 return $self->parseResult($text, $1, @_);
749             }
750 4986 50       9811 if ($$text =~ /^(\\x[0-9a-fA-F][0-9a-fA-F]?)/) {
751 0         0 return $self->parseResult($text, $1, @_);
752             }
753 4986 50       9410 if ($$text =~ /^(\\[0-7][0-7]?[0-7]?)/) {
754 0         0 return $self->parseResult($text, $1, @_);
755             }
756 4986         12171 return ''
757             }
758              
759             sub testInt {
760 63144     63145 1 106259 my $self = shift;
761 63144         90740 my $text = shift;
762 63144 100       117423 if ($self->engine->lastcharDeliminator) {
763 33241 100       103525 if ($$text =~ /^([+-]?\d+)/) {
764 314         998 return $self->parseResult($text, $1, @_);
765             }
766             }
767 62830         170874 return ''
768             }
769              
770             sub testKeyword {
771 372563     372564 1 571972 my $self = shift;
772 372563         528441 my $text = shift;
773 372563         516792 my $list = shift;
774 372563         639548 my $eng = $self->engine;
775 372563         711153 my $deliminators = $self->deliminators;
776 372563 100 100     689101 if (($eng->lastcharDeliminator) and ($$text =~ /^([^$deliminators]+)/)) {
777 72284         179765 my $match = $1;
778 72284         165173 my $l = $self->lists->{$list};
779 72284 50       153506 if (defined($l)) {
780 72284         710951 my @list = @$l;
781 72284         120560 my @rl = ();
782 72284 50       152613 unless ($self->keywordscase) {
783 72284         147040 @rl = grep { (lc($match) eq lc($_)) } @list;
  6179840         10224044  
784             } else {
785 0         0 @rl = grep { ($match eq $_) } @list;
  0         0  
786             }
787 72284 100       301334 if (@rl) {
788 5778         21052 return $self->parseResult($text, $match, @_);
789             }
790             } else {
791 0         0 $self->logwarning("list '$list' is not defined, failing test");
792             }
793             }
794 366785         1141983 return ''
795             }
796              
797             sub testLineContinue {
798 6210     6211 1 9751 my $self = shift;
799 6210         8669 my $text = shift;
800 6210         9050 my $lahead = shift;
801 6210 50       10272 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       13908 if ($$text =~ s/^(\\)(\n)/$2/) {
808 14         70 return $self->parseResult($text, "\\", $lahead, @_);
809             }
810             }
811 6196         16600 return ''
812             }
813              
814             sub testRangeDetect {
815 15354     15354 1 30374 my $self = shift;
816 15354         24514 my $text = shift;
817 15354         27297 my $char = shift;
818 15354         24248 my $char1 = shift;
819 15354         25731 my $insensitive = shift;
820 15354         38932 my $string = "$char\[^$char1\]+$char1";
821 15354         44464 return $self->testRegExpr($text, $string, $insensitive, 0, @_);
822             }
823              
824             sub testRegExpr {
825 1370061     1370061 1 2149617 my $self = shift;
826 1370061         1830692 my $text = shift;
827 1370061         1927376 my $reg = shift;
828 1370061         1796807 my $insensitive = shift;
829 1370061         1913728 my $dynamic = shift;
830 1370061 100       2344749 if ($dynamic) {
831 5299         9495 $reg = $self->capturedParse($reg);
832             }
833 1370061         2373066 my $eng = $self->engine;
834 1370061 100       4766933 if ($reg =~ s/^\^//) {
    100          
835 293923 100       610822 unless ($eng->linestart) {
836 283496         914435 return '';
837             }
838             } elsif ($reg =~ s/^\\(b)//i) {
839 310453         628085 my $lastchar = $self->engine->lastchar;
840 310453 100       767328 if ($1 eq 'b') {
841 309771 100       790276 if ($lastchar =~ /\w/) { return '' }
  130011         446021  
842             } else {
843 682 100       2217 if ($lastchar =~ /\W/) { return '' }
  308         1084  
844             }
845             }
846             # $reg = "^($reg)";
847 956246         2051293 $reg = "^$reg";
848 956246         1454438 my $pos;
849             # my @cap = ();
850 956246         1453648 my $sample = $$text;
851              
852             # emergency measurements to avoid exception (szabgab)
853 956246         1337903 $reg = eval { qr/$reg/ };
  956246         13936134  
854 956246 50       2379649 if ($@) {
855 0         0 warn $@;
856 0         0 return '';
857             }
858 956246 100       1606566 if ($insensitive) {
859 127708 100       617893 if ($sample =~ /$reg/ig) {
860 158         527 $pos = pos($sample);
861             # @cap = ($1, $2, $3, $4, $5, $6, $7, $8, $9);
862             # my @cap = ();
863 158 100       623 if ($#-) {
864 6     6   420 no strict 'refs';
  6         17  
  6         559  
865 58         265 my @cap = map {$$_} 1 .. $#-;
  84         567  
866 58         345 $self->captured(\@cap)
867             }
868             # my $r = 1;
869             # my $c = 1;
870             # my @cap = ();
871             # while ($r) {
872             # eval "if (defined\$$c) { push \@cap, \$$c } else { \$r = 0 }";
873             # $c ++;
874             # }
875             # if (@cap) { $self->captured(\@cap) };
876             }
877             } else {
878 828538 100       3551494 if ($sample =~ /$reg/g) {
879 13007         26883 $pos = pos($sample);
880             # @cap = ($1, $2, $3, $4, $5, $6, $7, $8, $9);
881             # my @cap = ();
882 13007 100       39721 if ($#-) {
883 6     6   41 no strict 'refs';
  6         14  
  6         1154  
884 1161         5106 my @cap = map {$$_} 1 .. $#-;
  1295         8067  
885 1161         6165 $self->captured(\@cap);
886             }
887             # my $r = 1;
888             # my $c = 1;
889             # my @cap = ();
890             # while ($r) {
891             # eval "if (defined\$$c) { push \@cap, \$$c } else { \$r = 0 }";
892             # $c ++;
893             # }
894             # if (@cap) { $self->captured(\@cap) };
895             }
896             }
897 956246 100 100     2078076 if (defined($pos) and ($pos > 0)) {
898 9835         23294 my $string = substr($$text, 0, $pos);
899 9835         29202 return $self->parseResult($text, $string, @_);
900             }
901 946411         3237124 return ''
902             }
903              
904             sub testStringDetect {
905 1692932     1692932 1 2266244 my $self = shift;
906 1692932         2168237 my $text = shift;
907 1692932         2135437 my $string = shift;
908 1692932         2029267 my $insensitive = shift;
909 1692932         2076035 my $dynamic = shift;
910 1692932 50       2666269 if ($dynamic) {
911 0         0 $string = $self->capturedParse($string);
912             }
913 1692932         2437505 my $test = substr($$text, 0, length($string));
914 1692932         2152234 my $bck = $test;
915 1692932 100       2547491 if ($insensitive) {
916 3672         6007 $string = lc($string);
917 3672         5516 $test = lc($test);
918             }
919 1692932 100       2696654 if ($string eq $test) {
920 570         1803 return $self->parseResult($text, $bck, @_);
921             }
922 1692362         3962990 return ''
923             }
924              
925              
926             1;
927              
928             __END__