|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Data::ModeMerge::Mode::Base;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $DATE = '2021-08-15'; # DATE  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $VERSION = '0.360'; # VERSION  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
31
 | 
 
 | 
 
 | 
  
31
  
 | 
 
 | 
16006
 | 
 use 5.010;  | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
101
 | 
    | 
| 
7
 | 
31
 | 
 
 | 
 
 | 
  
31
  
 | 
 
 | 
130
 | 
 use strict;  | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
    | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
573
 | 
    | 
| 
8
 | 
31
 | 
 
 | 
 
 | 
  
31
  
 | 
 
 | 
144
 | 
 use warnings;  | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
86
 | 
    | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
876
 | 
    | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #use Data::Dmp;  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #use Log::Any '$log';  | 
| 
13
 | 
31
 | 
 
 | 
 
 | 
  
31
  
 | 
 
 | 
150
 | 
 use Mo qw(build default);  | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
    | 
| 
 
 | 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
148
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #use Data::Clone qw/clone/;  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has merger => (is => 'rw');  | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has prefix => (is => 'rw');  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has prefix_re => (is => 'rw');  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has check_prefix_sub => (is => 'rw');  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has add_prefix_sub => (is => 'rw');  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 has remove_prefix_sub => (is => 'rw');  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub name {  | 
| 
25
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     die "Subclass must provide name()";  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub precedence_level {  | 
| 
29
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     die "Subclass must provide precedence_level()";  | 
| 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
31
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub default_prefix {  | 
| 
33
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     die "Subclass must provide default_prefix()";  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
35
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub default_prefix_re {  | 
| 
37
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     die "Subclass must provide default_prefix_re()";  | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub BUILD {  | 
| 
41
 | 
1980
 | 
 
 | 
 
 | 
  
1980
  
 | 
  
0
  
 | 
69668
 | 
     my ($self) = @_;  | 
| 
42
 | 
1980
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4394
 | 
     $self->prefix($self->default_prefix);  | 
| 
43
 | 
1980
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9509
 | 
     $self->prefix_re($self->default_prefix_re);  | 
| 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
46
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub check_prefix {  | 
| 
47
 | 
11471
 | 
 
 | 
 
 | 
  
11471
  
 | 
  
1
  
 | 
21866
 | 
     my ($self, $hash_key) = @_;  | 
| 
48
 | 
11471
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
16016
 | 
     if ($self->check_prefix_sub) {  | 
| 
49
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $self->check_prefix_sub->($hash_key);  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
51
 | 
11471
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34939
 | 
         $hash_key =~ $self->prefix_re;  | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub add_prefix {  | 
| 
56
 | 
101
 | 
 
 | 
 
 | 
  
101
  
 | 
  
1
  
 | 
1182
 | 
     my ($self, $hash_key) = @_;  | 
| 
57
 | 
101
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
253
 | 
     if ($self->add_prefix_sub) {  | 
| 
58
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
         $self->add_prefix_sub->($hash_key);  | 
| 
59
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
60
 | 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
401
 | 
         $self->prefix . $hash_key;  | 
| 
61
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub remove_prefix {  | 
| 
65
 | 
942
 | 
 
 | 
 
 | 
  
942
  
 | 
  
1
  
 | 
2863
 | 
     my ($self, $hash_key) = @_;  | 
| 
66
 | 
942
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1658
 | 
     if ($self->remove_prefix_sub) {  | 
| 
67
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
         $self->remove_prefix_sub->($hash_key);  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
69
 | 
932
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3006
 | 
         my $re = $self->prefix_re;  | 
| 
70
 | 
932
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4298
 | 
         $hash_key =~ s/$re//;  | 
| 
71
 | 
932
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2152
 | 
         $hash_key;  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub merge_ARRAY_ARRAY {  | 
| 
76
 | 
13
 | 
 
 | 
 
 | 
  
13
  
 | 
  
0
  
 | 
28
 | 
     my ($self, $key, $l, $r) = @_;  | 
| 
77
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     my $mm = $self->merger;  | 
| 
78
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
     my $c = $mm->config;  | 
| 
79
 | 
13
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
54
 | 
     return $self->merge_SCALAR_SCALAR($key, $l, $r) unless $c->recurse_array;  | 
| 
80
 | 
4
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
41
 | 
     return if $c->wanted_path && !$mm->_path_is_included($mm->path, $c->wanted_path);  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
82
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
     my @res;  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     my @backup;  | 
| 
84
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
     my $la = @$l;  | 
| 
85
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     my $lb = @$r;  | 
| 
86
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     push @{ $mm->path }, -1;  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
87
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
76
 | 
     for my $i (0..($la > $lb ? $la : $lb)-1) {  | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #print "DEBUG: merge_A_A: #$i: a->[$i]=".Data::Dumper->new([$l->[$i]])->Indent(0)->Terse(1)->Dump.", b->[$i]=".Data::Dumper->new([$r->[$i]])->Indent(0)->Terse(1)->Dump."\n";  | 
| 
89
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
45
 | 
         $mm->path->[-1] = $i;  | 
| 
90
 | 
6
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
70
 | 
         if ($i < $la && $i < $lb) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
91
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
             push @backup, $l->[$i];  | 
| 
92
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
             my ($subnewkey, $subres, $subbackup, $is_circular) = $mm->_merge($i, $l->[$i], $r->[$i], $c->default_mode);  | 
| 
93
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
9
 | 
             last if @{ $mm->errors };  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
94
 | 
5
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
56
 | 
             if ($is_circular) {  | 
| 
95
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 push @res, undef;  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 #print "DEBUG: pushing todo to mem<".$mm->cur_mem_key.">\n";  | 
| 
97
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 push @{ $mm->mem->{ $mm->cur_mem_key }{todo} }, sub {  | 
| 
98
 | 
  
0
  
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
0
 | 
                     my ($subnewkey, $subres, $subbackup) = @_;  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     #print "DEBUG: Entering todo subroutine (i=$i)\n";  | 
| 
100
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $res[$i] = $subres;  | 
| 
101
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
102
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             } else {  | 
| 
103
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
                 push @res, $subres;# if defined($newkey); = we allow DELETE on array?  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif ($i < $la) {  | 
| 
106
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
             push @res, $l->[$i];  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
108
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             push @res, $r->[$i];  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
111
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
     pop @{ $mm->path };  | 
| 
 
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
    | 
| 
112
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     ($key, \@res, \@backup);  | 
| 
113
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
114
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _prefilter_hash {  | 
| 
116
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
 
 | 
63
 | 
     my ($self, $h, $desc, $sub) = @_;  | 
| 
117
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     my $mm = $self->merger;  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
119
 | 
18
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
59
 | 
     if (ref($sub) ne 'CODE') {  | 
| 
120
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
         $mm->push_error("$desc failed: filter must be a coderef");  | 
| 
121
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         return;  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
124
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
     my $res = {};  | 
| 
125
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     for (keys %$h) {  | 
| 
126
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
         my @r = $sub->($_, $h->{$_});  | 
| 
127
 | 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
105
 | 
         while (my ($k, $v) = splice @r, 0, 2) {  | 
| 
128
 | 
21
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
41
 | 
             next unless defined $k;  | 
| 
129
 | 
17
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
23
 | 
             if (exists $res->{$k}) {  | 
| 
130
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
                 $mm->push_error("$desc failed; key conflict: ".  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                 "$_ -> $k, but key $k already exists");  | 
| 
132
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
                 return;  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
134
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
             $res->{$k} = $v;  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
138
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
     $res;  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # turn {[prefix]key => val, ...} into { key => [MODE, val], ...}, push  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # error if there's conflicting key  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _gen_left {  | 
| 
144
 | 
566
 | 
 
 | 
 
 | 
  
566
  
 | 
 
 | 
1212
 | 
     my ($self, $l, $mode, $esub, $ep, $ip, $epr, $ipr) = @_;  | 
| 
145
 | 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
984
 | 
     my $mm = $self->merger;  | 
| 
146
 | 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1892
 | 
     my $c = $mm->config;  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: Entering _gen_left(".dmp($l).", $mode, ...)\n";  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
150
 | 
566
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1812
 | 
     if ($c->premerge_pair_filter) {  | 
| 
151
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
         $l = $self->_prefilter_hash($l, "premerge filter left hash",  | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     $c->premerge_pair_filter);  | 
| 
153
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         return if @{ $mm->errors };  | 
| 
 
 | 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
    | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
156
 | 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1933
 | 
     my $hl = {};  | 
| 
157
 | 
562
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1047
 | 
     if ($c->parse_prefix) {  | 
| 
158
 | 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2539
 | 
         for (keys %$l) {  | 
| 
159
 | 
1171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1452
 | 
             my $do_parse = 1;  | 
| 
160
 | 
1171
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
3183
 | 
             $do_parse = 0 if $do_parse && $ep  &&  $mm->_in($_, $ep);  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
161
 | 
1171
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2936
 | 
             $do_parse = 0 if $do_parse && $ip  && !$mm->_in($_, $ip);  | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
162
 | 
1171
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2902
 | 
             $do_parse = 0 if $do_parse && $epr &&  /$epr/;  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
163
 | 
1171
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2834
 | 
             $do_parse = 0 if $do_parse && $ipr && !/$ipr/;  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
165
 | 
1171
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1597
 | 
             if ($do_parse) {  | 
| 
166
 | 
1128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1359
 | 
                 my $old = $_;  | 
| 
167
 | 
1128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1197
 | 
                 my $m2;  | 
| 
168
 | 
1128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2162
 | 
                 ($_, $m2) = $mm->remove_prefix($_);  | 
| 
169
 | 
1127
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
8298
 | 
                 next if $esub && !$esub->($_);  | 
| 
170
 | 
538
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
1118
 | 
                 if ($old ne $_ && exists($l->{$_})) {  | 
| 
171
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $mm->push_error("Conflict when removing prefix on left-side ".  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     "hash key: $old -> $_ but $_ already exists");  | 
| 
173
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     return;  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
175
 | 
538
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1642
 | 
                 $hl->{$_} = [$m2, $l->{$old}];  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } else {  | 
| 
177
 | 
43
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
97
 | 
                 next if $esub && !$esub->($_);  | 
| 
178
 | 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
125
 | 
                 $hl->{$_} = [$mode, $l->{$_}];  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
182
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
56
 | 
         for (keys %$l) {  | 
| 
183
 | 
27
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
50
 | 
             next if $esub && !$esub->($_);  | 
| 
184
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
             $hl->{$_} = [$mode, $l->{$_}];  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: Leaving _gen_left, result = ".dmp($hl)."\n";  | 
| 
189
 | 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1237
 | 
     $hl;  | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
191
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # turn {[prefix]key => val, ...} into { key => {MODE=>val, ...}, ...},  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # push error if there's conflicting key+MODE  | 
| 
194
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _gen_right {  | 
| 
195
 | 
561
 | 
 
 | 
 
 | 
  
561
  
 | 
 
 | 
1101
 | 
     my ($self, $r, $mode, $esub, $ep, $ip, $epr, $ipr) = @_;  | 
| 
196
 | 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
988
 | 
     my $mm = $self->merger;  | 
| 
197
 | 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1738
 | 
     my $c = $mm->config;  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: Entering _gen_right(".dmp($r).", $mode, ...)\n";  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
201
 | 
561
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1736
 | 
     if ($c->premerge_pair_filter) {  | 
| 
202
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
25
 | 
         $r = $self->_prefilter_hash($r, "premerge filter right hash",  | 
| 
203
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     $c->premerge_pair_filter);  | 
| 
204
 | 
7
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         return if @{ $mm->errors };  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
    | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
207
 | 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1844
 | 
     my $hr = {};  | 
| 
208
 | 
561
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
970
 | 
     if ($c->parse_prefix) {  | 
| 
209
 | 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3313
 | 
         for (keys %$r) {  | 
| 
210
 | 
1201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1490
 | 
             my $do_parse = 1;  | 
| 
211
 | 
1201
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
3129
 | 
             $do_parse = 0 if $do_parse && $ep  &&  $mm->_in($_, $ep);  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
212
 | 
1201
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2879
 | 
             $do_parse = 0 if $do_parse && $ip  && !$mm->_in($_, $ip);  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
213
 | 
1201
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2945
 | 
             $do_parse = 0 if $do_parse && $epr &&  /$epr/;  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
214
 | 
1201
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2969
 | 
             $do_parse = 0 if $do_parse && $ipr && !/$ipr/;  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
215
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
216
 | 
1201
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1625
 | 
             if ($do_parse) {  | 
| 
217
 | 
1155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1367
 | 
                 my $old = $_;  | 
| 
218
 | 
1155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1209
 | 
                 my $m2;  | 
| 
219
 | 
1155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2122
 | 
                 ($_, $m2) = $mm->remove_prefix($_);  | 
| 
220
 | 
1155
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
4678
 | 
                 next if $esub && !$esub->($_);  | 
| 
221
 | 
550
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
1362
 | 
                 if (exists $hr->{$_}{$m2}) {  | 
| 
222
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $mm->push_error("Conflict when removing prefix on right-side ".  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     "hash key: $old($m2) -> $_ ($m2) but $_ ($m2) ".  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                     "already exists");  | 
| 
225
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     return;  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
227
 | 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1473
 | 
                 $hr->{$_}{$m2} = $r->{$old};  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } else {  | 
| 
229
 | 
46
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
83
 | 
                 next if $esub && !$esub->($_);  | 
| 
230
 | 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
113
 | 
                 $hr->{$_} = {$mode => $r->{$_}};  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
234
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
         for (keys %$r) {  | 
| 
235
 | 
25
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
49
 | 
             next if $esub && !$esub->($_);  | 
| 
236
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
64
 | 
             $hr->{$_} = {$mode => $r->{$_}}  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: Leaving _gen_right, result = ".dmp($hr)."\n";  | 
| 
240
 | 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1096
 | 
     $hr;  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
242
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # merge two hashes which have been prepared by _gen_left and  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # _gen_right, will result in { key => [final_mode, val], ... }  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _merge_gen {  | 
| 
246
 | 
554
 | 
 
 | 
 
 | 
  
554
  
 | 
 
 | 
1009
 | 
     my ($self, $hl, $hr, $mode, $em, $im, $emr, $imr) = @_;  | 
| 
247
 | 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1020
 | 
     my $mm = $self->merger;  | 
| 
248
 | 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1731
 | 
     my $c = $mm->config;  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: Entering _merge_gen(".dmp($hl).", ".dmp($hr).", $mode, ...)\n";  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
252
 | 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1553
 | 
     my $res = {};  | 
| 
253
 | 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
786
 | 
     my $backup = {};  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
255
 | 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1664
 | 
     my %k = map {$_=>1} keys(%$hl), keys(%$hr);  | 
| 
 
 | 
1186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2380
 | 
    | 
| 
256
 | 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
853
 | 
     push @{ $mm->path }, "";  | 
| 
 
 | 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1037
 | 
    | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   K:  | 
| 
258
 | 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2963
 | 
     for my $k (keys %k) {  | 
| 
259
 | 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
856
 | 
         my @o;  | 
| 
260
 | 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1216
 | 
         $mm->path->[-1] = $k;  | 
| 
261
 | 
706
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3089
 | 
         my $do_merge = 1;  | 
| 
262
 | 
706
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
2005
 | 
         $do_merge = 0 if $do_merge && $em  &&  $mm->_in($k, $em);  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
263
 | 
706
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1762
 | 
         $do_merge = 0 if $do_merge && $im  && !$mm->_in($k, $im);  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
264
 | 
706
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1804
 | 
         $do_merge = 0 if $do_merge && $emr && $k =~ /$emr/;  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
265
 | 
706
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1776
 | 
         $do_merge = 0 if $do_merge && $imr && $k !~ /$imr/;  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
267
 | 
706
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1049
 | 
         if (!$do_merge) {  | 
| 
268
 | 
47
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
128
 | 
             $res->{$k} = $hl->{$k} if $hl->{$k};  | 
| 
269
 | 
47
 | 
 
 | 
 
 | 
 
 | 
 
 | 
75
 | 
             next K;  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
272
 | 
659
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
2020
 | 
         $backup->{$k} = $hl->{$k}[1] if $hl->{$k} && $hr->{$k};  | 
| 
273
 | 
659
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1189
 | 
         if ($hl->{$k}) {  | 
| 
274
 | 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
859
 | 
             push @o, $hl->{$k};  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
276
 | 
659
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1029
 | 
         if ($hr->{$k}) {  | 
| 
277
 | 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
948
 | 
             my %m = map {$_=>$mm->modes->{$_}->precedence_level} keys %{ $hr->{$k} };  | 
| 
 
 | 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1121
 | 
    | 
| 
 
 | 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1398
 | 
    | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             #print "DEBUG: \\%m=".Data::Dumper->new([\%m])->Indent(0)->Terse(1)->Dump."\n";  | 
| 
279
 | 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1244
 | 
             push @o, map { [$_, $hr->{$k}{$_}] } sort { $m{$b} <=> $m{$a} } keys %m;  | 
| 
 
 | 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1607
 | 
    | 
| 
 
 | 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
79
 | 
    | 
| 
280
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
281
 | 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1745
 | 
         my $final_mode;  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         my $is_circular;  | 
| 
283
 | 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $v;  | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #print "DEBUG: k=$k, o=".Data::Dumper->new([\@o])->Indent(0)->Terse(1)->Dump."\n";  | 
| 
285
 | 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1331
 | 
         for my $i (0..$#o) {  | 
| 
286
 | 
1112
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1715
 | 
             if ($i == 0) {  | 
| 
287
 | 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1244
 | 
                 my $mh = $mm->modes->{$o[$i][0]};  | 
| 
288
 | 
659
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
4936
 | 
                 if (@o == 1 &&  | 
| 
 
 | 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         (($hl->{$k} && $mh->can("merge_left_only")) ||  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          ($hr->{$k} && $mh->can("merge_right_only")))) {  | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     # there's only left-side or right-side  | 
| 
292
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
8
 | 
                     my $meth = $hl->{$k} ? "merge_left_only" : "merge_right_only";  | 
| 
293
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
                     my ($subnewkey, $v1, $subbackup, $is_circular, $newmode) = $mh->$meth($k, $o[$i][1]); # XXX handle circular?  | 
| 
294
 | 
3
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
                     next K unless defined($subnewkey);  | 
| 
295
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $final_mode = $newmode;  | 
| 
296
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                     $v = $v1;  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 } else {  | 
| 
298
 | 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
928
 | 
                     $final_mode = $o[$i][0];  | 
| 
299
 | 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1031
 | 
                     $v = $o[$i][1];  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             } else {  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 my $m = $mm->combine_rules->{"$final_mode+$o[$i][0]"}  | 
| 
303
 | 
453
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
809
 | 
                     or do {  | 
| 
304
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
                         $mm->push_error("Can't merge $final_mode + $o[$i][0]");  | 
| 
305
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
                         return;  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     };  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 #print "DEBUG: merge $final_mode+$o[$i][0] = $m->[0], $m->[1]\n";  | 
| 
308
 | 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1970
 | 
                 my ($subnewkey, $subbackup);  | 
| 
309
 | 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1170
 | 
                 ($subnewkey, $v, $subbackup, $is_circular) = $mm->_merge($k, $v, $o[$i][1], $m->[0]);  | 
| 
310
 | 
445
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
615
 | 
                 return if @{ $mm->errors };  | 
| 
 
 | 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
723
 | 
    | 
| 
311
 | 
409
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
2121
 | 
                 if ($is_circular) {  | 
| 
312
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
                     if ($i < $#o) {  | 
| 
313
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
                         $mm->push_error("Can't handle circular at $i of $#o merges (mode $m->[0]): not the last merge");  | 
| 
314
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
                         return;  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     }  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     #print "DEBUG: pushing todo to mem<".$mm->cur_mem_key.">\n";  | 
| 
317
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
                     push @{ $mm->mem->{ $mm->cur_mem_key }{todo} }, sub {  | 
| 
318
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
4
 | 
                         my ($subnewkey, $subres, $subbackup) = @_;  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         #print "DEBUG: Entering todo subroutine (k=$k)\n";  | 
| 
320
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
                         my $final_mode = $m->[1];  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         #XXX return unless defined($subnewkey);  | 
| 
322
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
                         $res->{$k} = [$m->[1], $subres];  | 
| 
323
 | 
2
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4
 | 
                         if ($c->readd_prefix) {  | 
| 
324
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             # XXX if there is a conflict error in  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                             # _readd_prefix, how to adjust path?  | 
| 
326
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
                             $self->_readd_prefix($res, $k, $c->default_mode);  | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         } else {  | 
| 
328
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                             $res->{$k} = $res->{$k}[1];  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         }  | 
| 
330
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
                     };  | 
| 
331
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
                     delete $res->{$k};  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
333
 | 
408
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
866
 | 
                 next K unless defined $subnewkey;  | 
| 
334
 | 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
677
 | 
                 $final_mode = $m->[1];  | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
337
 | 
554
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1979
 | 
         $res->{$k} = [$final_mode, $v] unless $is_circular;  | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
339
 | 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
691
 | 
     pop @{ $mm->path };  | 
| 
 
 | 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
831
 | 
    | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: Leaving _merge_gen, res = ".dmp($res)."\n";  | 
| 
341
 | 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3256
 | 
     ($res, $backup);  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # hh is {key=>[MODE, val], ...} which is the format returned by _merge_gen  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _readd_prefix {  | 
| 
346
 | 
508
 | 
 
 | 
 
 | 
  
508
  
 | 
 
 | 
2492
 | 
     my ($self, $hh, $k, $defmode) = @_;  | 
| 
347
 | 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
789
 | 
     my $mm = $self->merger;  | 
| 
348
 | 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1475
 | 
     my $c = $mm->config;  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
350
 | 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1366
 | 
     my $m = $hh->{$k}[0];  | 
| 
351
 | 
508
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
781
 | 
     if ($m eq $defmode) {  | 
| 
352
 | 
443
 | 
 
 | 
 
 | 
 
 | 
 
 | 
934
 | 
         $hh->{$k} = $hh->{$k}[1];  | 
| 
353
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
354
 | 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
112
 | 
         my $kp = $mm->modes->{$m}->add_prefix($k);  | 
| 
355
 | 
65
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
300
 | 
         if (exists $hh->{$kp}) {  | 
| 
356
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             $mm->push_error("BUG: conflict when re-adding prefix after merge: $kp");  | 
| 
357
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             return;  | 
| 
358
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
359
 | 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
124
 | 
         $hh->{$kp} = $hh->{$k}[1];  | 
| 
360
 | 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
158
 | 
         delete $hh->{$k};  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub merge_HASH_HASH {  | 
| 
365
 | 
304
 | 
 
 | 
 
 | 
  
304
  
 | 
  
0
  
 | 
591
 | 
     my ($self, $key, $l, $r, $mode) = @_;  | 
| 
366
 | 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
637
 | 
     my $mm = $self->merger;  | 
| 
367
 | 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1087
 | 
     my $c = $mm->config;  | 
| 
368
 | 
304
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
1342
 | 
     $mode //= $c->default_mode;  | 
| 
369
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: entering merge_H_H(".dmp($l).", ".dmp($r).", $mode), config=($c)=",dmp($c),"\n";  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #$log->trace("using config($c)");  | 
| 
371
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
372
 | 
304
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1947
 | 
     return $self->merge_SCALAR_SCALAR($key, $l, $r) unless $c->recurse_hash;  | 
| 
373
 | 
300
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
813
 | 
     return if $c->wanted_path && !$mm->_path_is_included($mm->path, $c->wanted_path);  | 
| 
374
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
375
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # STEP 1. MERGE LEFT & RIGHT OPTIONS KEY  | 
| 
376
 | 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1169
 | 
     my $config_replaced;  | 
| 
377
 | 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
374
 | 
     my $orig_c = $c;  | 
| 
378
 | 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
552
 | 
     my $ok = $c->options_key;  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     {  | 
| 
380
 | 
298
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
572
 | 
         last unless defined $ok;  | 
| 
 
 | 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
554
 | 
    | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
382
 | 
297
 | 
 
 | 
 
 | 
  
611
  
 | 
 
 | 
1511
 | 
         my $okl = $self->_gen_left ($l, $mode, sub {$_[0] eq $ok});  | 
| 
 
 | 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2082
 | 
    | 
| 
383
 | 
296
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
787
 | 
         return if @{ $mm->errors };  | 
| 
 
 | 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
595
 | 
    | 
| 
384
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
385
 | 
292
 | 
 
 | 
 
 | 
  
626
  
 | 
 
 | 
2340
 | 
         my $okr = $self->_gen_right($r, $mode, sub {$_[0] eq $ok});  | 
| 
 
 | 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2210
 | 
    | 
| 
386
 | 
292
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
723
 | 
         return if @{ $mm->errors };  | 
| 
 
 | 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
583
 | 
    | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
388
 | 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1563
 | 
         push @{ $mm->path }, $ok;  | 
| 
 
 | 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
509
 | 
    | 
| 
389
 | 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1459
 | 
         my ($res, $backup);  | 
| 
390
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         {  | 
| 
391
 | 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
355
 | 
             local $c->{readd_prefix} = 0;  | 
| 
 
 | 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
634
 | 
    | 
| 
392
 | 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
825
 | 
             ($res, $backup) = $self->_merge_gen($okl, $okr, $mode);  | 
| 
393
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
394
 | 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
422
 | 
         pop @{ $mm->path };  | 
| 
 
 | 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
484
 | 
    | 
| 
395
 | 
292
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1215
 | 
         return if @{ $mm->errors };  | 
| 
 
 | 
292
 | 
 
 | 
 
 | 
 
 | 
 
 | 
519
 | 
    | 
| 
396
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #print "DEBUG: merge options key (".dmp($okl).", ".dmp($okr).") = ".dmp($res)."\n";  | 
| 
398
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
399
 | 
291
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1658
 | 
         $res = $res->{$ok} ? $res->{$ok}[1] : undef;  | 
| 
400
 | 
291
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
864
 | 
         if (defined($res) && ref($res) ne 'HASH') {  | 
| 
401
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
             $mm->push_error("Invalid options key after merge: value must be hash");  | 
| 
402
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
             return;  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
404
 | 
285
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
984
 | 
         last unless keys %$res;  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #$log->tracef("cloning config ...");  | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         # Data::Clone by default does *not* deep-copy object  | 
| 
407
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #my $c2 = clone($c);  | 
| 
408
 | 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
416
 | 
         my $c2 = bless({ %$c }, ref($c));  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
410
 | 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
137
 | 
         for (keys %$res) {  | 
| 
411
 | 
62
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
112
 | 
             if ($c->allow_override) {  | 
| 
412
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
                 my $re = $c->allow_override;  | 
| 
413
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
28
 | 
                 if (!/$re/) {  | 
| 
414
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
                     $mm->push_error("Configuration in options key `$_` not allowed by allow_override $re");  | 
| 
415
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
                     return;  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
418
 | 
60
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
239
 | 
             if ($c->disallow_override) {  | 
| 
419
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
                 my $re = $c->disallow_override;  | 
| 
420
 | 
4
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
20
 | 
                 if (/$re/) {  | 
| 
421
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
                     $mm->push_error("Configuration in options key `$_` not allowed by disallow_override $re");  | 
| 
422
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
                     return;  | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }  | 
| 
424
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
425
 | 
58
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
212
 | 
             if ($mm->_in($_, $c->_config_config)) {  | 
| 
426
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
                 $mm->push_error("Configuration not allowed in options key: $_");  | 
| 
427
 | 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
                 return;  | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
429
 | 
54
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
140
 | 
             if ($_ ne $ok && !$mm->_in($_, $c->_config_ok)) {  | 
| 
430
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
                 $mm->push_error("Unknown configuration in options key: $_");  | 
| 
431
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
                 return;  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
433
 | 
53
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
225
 | 
             $c2->$_($res->{$_}) unless $_ eq $ok;  | 
| 
434
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
435
 | 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
273
 | 
         $mm->config($c2);  | 
| 
436
 | 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
146
 | 
         $config_replaced++;  | 
| 
437
 | 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
128
 | 
         $c = $c2;  | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #$log->trace("config now changed to $c2");  | 
| 
439
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
440
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
441
 | 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
619
 | 
     my $sp = $c->set_prefix;  | 
| 
442
 | 
277
 | 
 
 | 
 
 | 
 
 | 
 
 | 
838
 | 
     my $saved_prefixes;  | 
| 
443
 | 
277
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
503
 | 
     if (defined($sp)) {  | 
| 
444
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
25
 | 
         if (ref($sp) ne 'HASH') {  | 
| 
445
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
             $mm->push_error("Invalid config value `set_prefix`: must be a hash");  | 
| 
446
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
             return;  | 
| 
447
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
448
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
         $saved_prefixes = {};  | 
| 
449
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         for my $mh (values %{ $mm->modes }) {  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
450
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
             my $n = $mh->name;  | 
| 
451
 | 
30
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
67
 | 
             if ($sp->{$n}) {  | 
| 
452
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
                 $saved_prefixes->{$n} = {  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     prefix => $mh->prefix,  | 
| 
454
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     prefix_re => $mh->prefix_re,  | 
| 
455
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     check_prefix_sub => $mh->check_prefix_sub,  | 
| 
456
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     add_prefix_sub => $mh->add_prefix_sub,  | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                     remove_prefix_sub => $mh->remove_prefix_sub,  | 
| 
458
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 };  | 
| 
459
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
91
 | 
                 $mh->prefix($sp->{$n});  | 
| 
460
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
                 my $re = quotemeta($sp->{$n});  | 
| 
461
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
103
 | 
                 $mh->prefix_re(qr/^$re/);  | 
| 
462
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
                 $mh->check_prefix_sub(undef);  | 
| 
463
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
                 $mh->add_prefix_sub(undef);  | 
| 
464
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
                 $mh->remove_prefix_sub(undef);  | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
466
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
469
 | 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
540
 | 
     my $ep = $c->exclude_parse;  | 
| 
470
 | 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1000
 | 
     my $ip = $c->include_parse;  | 
| 
471
 | 
275
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
972
 | 
     if (defined($ep) && ref($ep) ne 'ARRAY') {  | 
| 
472
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         $mm->push_error("Invalid config value `exclude_parse`: must be an array");  | 
| 
473
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
         return;  | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
475
 | 
273
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
902
 | 
     if (defined($ip) && ref($ip) ne 'ARRAY') {  | 
| 
476
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         $mm->push_error("Invalid config value `include_parse`: must be an array");  | 
| 
477
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
         return;  | 
| 
478
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
479
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
480
 | 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
477
 | 
     my $epr = $c->exclude_parse_regex;  | 
| 
481
 | 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
899
 | 
     my $ipr = $c->include_parse_regex;  | 
| 
482
 | 
271
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
906
 | 
     if (defined($epr)) {  | 
| 
483
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         eval { $epr = qr/$epr/ };  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
82
 | 
    | 
| 
484
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
14
 | 
         if ($@) {  | 
| 
485
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
             $mm->push_error("Invalid config value `exclude_parse_regex`: invalid regex: $@");  | 
| 
486
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
             return;  | 
| 
487
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
489
 | 
270
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
453
 | 
     if (defined($ipr)) {  | 
| 
490
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         eval { $ipr = qr/$ipr/ };  | 
| 
 
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
    | 
| 
491
 | 
5
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
12
 | 
         if ($@) {  | 
| 
492
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
             $mm->push_error("Invalid config value `include_parse_regex`: invalid regex: $@");  | 
| 
493
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
             return;  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
495
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
497
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # STEP 2. PREPARE LEFT HASH  | 
| 
498
 | 
269
 | 
  
100
  
 | 
 
 | 
  
586
  
 | 
 
 | 
1114
 | 
     my $hl = $self->_gen_left ($l, $mode, sub {defined($ok) ? $_[0] ne $ok : 1}, $ep, $ip, $epr, $ipr);  | 
| 
 
 | 
586
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1801
 | 
    | 
| 
499
 | 
269
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
671
 | 
     return if @{ $mm->errors };  | 
| 
 
 | 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
551
 | 
    | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # STEP 3. PREPARE RIGHT HASH  | 
| 
502
 | 
269
 | 
  
100
  
 | 
 
 | 
  
600
  
 | 
 
 | 
2028
 | 
     my $hr = $self->_gen_right($r, $mode, sub {defined($ok) ? $_[0] ne $ok : 1}, $ep, $ip, $epr, $ipr);  | 
| 
 
 | 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1866
 | 
    | 
| 
503
 | 
269
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
624
 | 
     return if @{ $mm->errors };  | 
| 
 
 | 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
526
 | 
    | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: hl=".Data::Dumper->new([$hl])->Indent(0)->Terse(1)->Dump."\n";  | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: hr=".Data::Dumper->new([$hr])->Indent(0)->Terse(1)->Dump."\n";  | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
508
 | 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1551
 | 
     my $em = $c->exclude_merge;  | 
| 
509
 | 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
853
 | 
     my $im = $c->include_merge;  | 
| 
510
 | 
269
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
1040
 | 
     if (defined($em) && ref($em) ne 'ARRAY') {  | 
| 
511
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         $mm->push_error("Invalid config value `exclude_marge`: must be an array");  | 
| 
512
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
         return;  | 
| 
513
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
514
 | 
267
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
572
 | 
     if (defined($im) && ref($im) ne 'ARRAY') {  | 
| 
515
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         $mm->push_error("Invalid config value `include_merge`: must be an array");  | 
| 
516
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
         return;  | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
518
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
519
 | 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
493
 | 
     my $emr = $c->exclude_merge_regex;  | 
| 
520
 | 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
861
 | 
     my $imr = $c->include_merge_regex;  | 
| 
521
 | 
265
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
846
 | 
     if (defined($emr)) {  | 
| 
522
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
         eval { $emr = qr/$emr/ };  | 
| 
 
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
104
 | 
    | 
| 
523
 | 
13
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
         if ($@) {  | 
| 
524
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
             $mm->push_error("Invalid config value `exclude_merge_regex`: invalid regex: $@");  | 
| 
525
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
             return;  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
528
 | 
263
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
452
 | 
     if (defined($imr)) {  | 
| 
529
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
         eval { $imr = qr/$imr/ };  | 
| 
 
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
88
 | 
    | 
| 
530
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
19
 | 
         if ($@) {  | 
| 
531
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
             $mm->push_error("Invalid config value `include_merge_regex`: invalid regex: $@");  | 
| 
532
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
             return;  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
534
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
535
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # STEP 4. MERGE LEFT & RIGHT  | 
| 
537
 | 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
525
 | 
     my ($res, $backup) = $self->_merge_gen($hl, $hr, $mode, $em, $im, $emr, $imr);  | 
| 
538
 | 
262
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
569
 | 
     return if @{ $mm->errors };  | 
| 
 
 | 
262
 | 
 
 | 
 
 | 
 
 | 
 
 | 
462
 | 
    | 
| 
539
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: intermediate res(5) = ".Data::Dumper->new([$res])->Indent(0)->Terse(1)->Dump."\n";  | 
| 
541
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
542
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # STEP 5. TURN BACK {key=>[MODE=>val]}, ...} INTO {(prefix)key => val, ...}  | 
| 
543
 | 
218
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
1179
 | 
     if ($c->readd_prefix) {  | 
| 
544
 | 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
596
 | 
         for my $k (keys %$res) {  | 
| 
545
 | 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
872
 | 
             $self->_readd_prefix($res, $k, $c->default_mode);  | 
| 
546
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
548
 | 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
155
 | 
         $res->{$_} = $res->{$_}[1] for keys %$res;  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
550
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
551
 | 
218
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
484
 | 
     if ($saved_prefixes) {  | 
| 
552
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
         for (keys %$saved_prefixes) {  | 
| 
553
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
             my $mh = $mm->modes->{$_};  | 
| 
554
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
             my $s = $saved_prefixes->{$_};  | 
| 
555
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
             $mh->prefix($s->{prefix});  | 
| 
556
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
             $mh->prefix_re($s->{prefix_re});  | 
| 
557
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
             $mh->check_prefix_sub($s->{check_prefix_sub});  | 
| 
558
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
24
 | 
             $mh->add_prefix_sub($s->{add_prefix_sub});  | 
| 
559
 | 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
23
 | 
             $mh->remove_prefix_sub($s->{remove_prefix_sub});  | 
| 
560
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # restore config  | 
| 
564
 | 
218
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
726
 | 
     if ($config_replaced) {  | 
| 
565
 | 
44
 | 
 
 | 
 
 | 
 
 | 
 
 | 
66
 | 
         $mm->config($orig_c);  | 
| 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #print "DEBUG: Restored config, config=", dmp($mm->config), "\n";  | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: backup = ".Data::Dumper->new([$backup])->Indent(0)->Terse(1)->Dump."\n";  | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #print "DEBUG: leaving merge_H_H, result = ".dmp($res)."\n";  | 
| 
571
 | 
218
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1175
 | 
     ($key, $res, $backup);  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: Base class for Data::ModeMerge mode handler  | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =pod  | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =encoding UTF-8  | 
| 
582
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
583
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Data::ModeMerge::Mode::Base - Base class for Data::ModeMerge mode handler  | 
| 
586
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 VERSION  | 
| 
588
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
589
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This document describes version 0.360 of Data::ModeMerge::Mode::Base (from Perl distribution Data-ModeMerge), released on 2021-08-15.  | 
| 
590
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
591
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SYNOPSIS  | 
| 
592
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
593
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
  use Data::ModeMerge;  | 
| 
594
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is the base class for mode type handlers.  | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =for Pod::Coverage ^(BUILD|merge_.+)$  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
601
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 ATTRIBUTES  | 
| 
602
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
603
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 merger  | 
| 
604
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
605
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 prefix  | 
| 
606
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 prefix_re  | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
609
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 check_prefix_sub  | 
| 
610
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 add_prefix_sub  | 
| 
612
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 remove_prefix_sub  | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
615
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 METHODS  | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 name  | 
| 
618
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
619
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Return name of mode. Subclass must override this method.  | 
| 
620
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
621
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 precedence_level  | 
| 
622
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
623
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Return precedence level, which is a number. The greater the number,  | 
| 
624
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the higher the precedence. Subclass must override this method.  | 
| 
625
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
626
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 default_prefix  | 
| 
627
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
628
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Return default prefix. Subclass must override this method.  | 
| 
629
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
630
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 default_prefix_re  | 
| 
631
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
632
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Return default prefix regex. Subclass must override this method.  | 
| 
633
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
634
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 check_prefix($hash_key)  | 
| 
635
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
636
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Return true if hash key has prefix for this mode.  | 
| 
637
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
638
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 add_prefix($hash_key)  | 
| 
639
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
640
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Return hash key with added prefix of this mode.  | 
| 
641
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
642
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head2 remove_prefix($hash_key)  | 
| 
643
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
644
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Return hash key with prefix of this mode prefix removed.  | 
| 
645
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
646
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 HOMEPAGE  | 
| 
647
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
648
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Please visit the project's homepage at L<https://metacpan.org/release/Data-ModeMerge>.  | 
| 
649
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
650
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 SOURCE  | 
| 
651
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
652
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Source repository is at L<https://github.com/perlancar/perl-Data-ModeMerge>.  | 
| 
653
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
654
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 BUGS  | 
| 
655
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
656
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 Please report any bugs or feature requests on the bugtracker website L<https://rt.cpan.org/Public/Dist/Display.html?Name=Data-ModeMerge>  | 
| 
657
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
658
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 When submitting a bug or request, please include a test-file or a  | 
| 
659
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 patch to an existing test-file that illustrates the bug or desired  | 
| 
660
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 feature.  | 
| 
661
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
662
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 AUTHOR  | 
| 
663
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
664
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 perlancar <perlancar@cpan.org>  | 
| 
665
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
666
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 COPYRIGHT AND LICENSE  | 
| 
667
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
668
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This software is copyright (c) 2021, 2016, 2015, 2013, 2012, 2011, 2010 by perlancar <perlancar@cpan.org>.  | 
| 
669
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
670
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is free software; you can redistribute it and/or modify it under  | 
| 
671
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 the same terms as the Perl 5 programming language system itself.  | 
| 
672
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
673
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  |