|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
  
 
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package PMLTQ::Suggest;  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 our $AUTHORITY = 'cpan:MATY';  | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $PMLTQ::Suggest::VERSION = '1.1.1';  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # ABSTRACT: Tool for generating simple PMLTQ query based on given nodes  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 NAME  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 PMLTQ::Suggest - Tool for generating simple PMLTQ query based on given nodes  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =head1 DESCRIPTION  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 This is an implementation of a Suggest server and a plugin for PML-TQ command-line client.  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 =cut  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
16
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
14
 | 
 use Scalar::Util qw(weaken);  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
    | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
134
 | 
    | 
| 
17
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
997
 | 
 use PMLTQ::Common qw(:all);  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21638
 | 
    | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
475
 | 
    | 
| 
18
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
23
 | 
 use Treex::PML::Schema::Constants;  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
182
 | 
    | 
| 
19
 | 
2
 | 
 
 | 
 
 | 
  
2
  
 | 
 
 | 
11
 | 
 use PMLTQ::Suggest::Utils;  | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
 
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
    | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub make_pmltq {  | 
| 
22
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
0
  
 | 
23
 | 
   my ($positions,%opts)=@_;  | 
| 
23
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
   my @open_files;      | 
| 
24
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
   my %cur_fsfiles; @cur_fsfiles{@open_files}=();  | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # my $keep_cur;  | 
| 
26
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   my %fsfiles;  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my @new_fsfiles;  | 
| 
28
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
   foreach my $f (map $_->[0], @$positions) {  | 
| 
29
 | 
15
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
74
 | 
     next if exists $fsfiles{$f};  | 
| 
30
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
       my $fsfile = PMLTQ::Suggest::Utils::open_file($f);  | 
| 
31
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
       my @new = ($fsfile, PMLTQ::Suggest::Utils::GetSecondaryFiles($fsfile));  | 
| 
32
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
       push @new_fsfiles, @new;  | 
| 
33
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
       push @open_files, @new;  | 
| 
34
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
974
 | 
       $fsfiles{$_->filename}=$_ for @new; # including $fsfile  | 
| 
35
 | 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3283
 | 
       $fsfiles{$f}=$fsfile; # $f may be different from $fsfile->filename  | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
37
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
   my @nodes;  | 
| 
38
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
   for my $pos (@$positions) {  | 
| 
39
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
     my $win = { FSFile => $fsfiles{$pos->[0]} };  | 
| 
40
 | 
15
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
53
 | 
     unless (PMLTQ::Suggest::Utils::apply_file_suffix($win,$pos->[1]) and $win->{currentNode}) {  | 
| 
41
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       warn "Didn't find node [@$pos, @{[%$win]}]\n";  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
42
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return;  | 
| 
43
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
44
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
60
 | 
     push @nodes, [ $win->{currentNode}, $win->{FSFile} ];  | 
| 
45
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
46
 | 
8
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
29
 | 
   print STDERR "generating query\n" if $opts{verbose};  | 
| 
47
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
   return nodes_to_pmltq(\@nodes,\%opts);  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
51
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
52
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub nodes_to_pmltq {  | 
| 
54
 | 
8
 | 
 
 | 
 
 | 
  
8
  
 | 
  
0
  
 | 
16
 | 
   my ($nodes,$opts)=@_;  | 
| 
55
 | 
8
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
22
 | 
   $opts||={};  | 
| 
56
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
12
 | 
   my %id_member;  | 
| 
57
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
   my $name = 'a';  | 
| 
58
 | 
8
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
25
 | 
   $name++ while $opts->{reserved_names}  && exists($opts->{reserved_names}{$name});  | 
| 
59
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
9
 | 
   my %node2name;  | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $opts->{id2name} = { map {  | 
| 
61
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
     my $n = $_->[0];  | 
| 
 
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
    | 
| 
62
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
     my $t = $n->type;  | 
| 
63
 | 
15
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
173
 | 
     my $id_member = ( $id_member{$t}||=_id_member_name($t) );  | 
| 
64
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
87
 | 
     my $var = $node2name{$n} = $name++;  | 
| 
65
 | 
15
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
44
 | 
     $name++ while $opts->{reserved_names}  && exists($opts->{reserved_names}{$name});  | 
| 
66
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
     ($n->{$id_member} => $var)  | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } @$nodes };  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # discover relations;  | 
| 
70
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
   my %marked;  | 
| 
71
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
   @marked{map $_->[0], @$nodes}=(); # undef by default, 1 if connected  | 
| 
72
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
   my %parents=();  | 
| 
73
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
   my %connect;  | 
| 
74
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
20
 | 
   for my $m (@$nodes) {  | 
| 
75
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
     my ($n,$fsfile)=@$m;  | 
| 
76
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
44
 | 
     my $parent = $n->parent;  | 
| 
77
 | 
15
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
90
 | 
     $parents{$parent}||=$n;  | 
| 
78
 | 
15
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
76
 | 
     if ($parent and exists($marked{$parent})) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
79
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       push @{$connect{$n->parent}{child}}, $n;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # print STDERR "$node2name{$n->parent} has child $node2name{$n}\n";  | 
| 
81
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
       $marked{$n}=1;  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($parents{$parent}!=$n) {  | 
| 
83
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
       push @{$connect{$parents{$parent}}{sibling}}, $n;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
    | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # print STDERR "$node2name{$parents{$parent}} has sibling $node2name{$n}\n";  | 
| 
85
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
       $marked{$n}=1;  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
87
 | 
13
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
39
 | 
       $parent = $parent && $parent->parent;  | 
| 
88
 | 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
61
 | 
       while ($parent) {  | 
| 
89
 | 
25
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
80
 | 
         if (exists $marked{$parent}) {  | 
| 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           # print STDERR "$node2name{$parent} has descendant $node2name{$n}\n";  | 
| 
91
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
           push @{$connect{$parent}{descendant}}, $n;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
    | 
| 
92
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4
 | 
           $marked{$n}=1;  | 
| 
93
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
           last;  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
95
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
         $parent = $parent->parent;  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
99
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
   $opts->{connect}=\%connect;  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return join(";\n\n", map {  | 
| 
101
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
     node_to_pmltq($_->[0],$_->[1],$opts)}  | 
| 
102
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
                 grep { !$marked{$_->[0]} } @$nodes);  | 
| 
 
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
39
 | 
    | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub node_to_pmltq {  | 
| 
106
 | 
15
 | 
 
 | 
 
 | 
  
15
  
 | 
  
0
  
 | 
37
 | 
   my ($node,$fsfile,$opts)=@_;  | 
| 
107
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
37
 | 
   return unless $node;  | 
| 
108
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
   my $type = $node->type;  | 
| 
109
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
120
 | 
   return unless $type;  | 
| 
110
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
   my $out='';  | 
| 
111
 | 
15
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
52
 | 
   my $indent = $opts->{indent} || '';  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
113
 | 
15
 | 
 
 | 
  
 33
  
 | 
 
 | 
 
 | 
62
 | 
   my $var = $opts->{id2name} && $opts->{id2name}{$node->{_id_member_name($node->type)}};  | 
| 
114
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
126
 | 
   $var = ' $'.$var.' := ' if $var;  | 
| 
115
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
53
 | 
   $out .= PMLTQ::Common::DeclToQueryType($type).$var." [\n";  | 
| 
116
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
492
 | 
   foreach my $attr ('#name',$type->get_normal_fields) {  | 
| 
117
 | 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7396
 | 
     my $m = $type->get_member_by_name($attr);  | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # next if $m and $m->get_role() eq '#ID';  | 
| 
119
 | 
386
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2178
 | 
     my $val = $node->{$attr};  | 
| 
120
 | 
386
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
630
 | 
     next unless defined $val;  | 
| 
121
 | 
125
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
192
 | 
     $m = $type->get_member_by_name($attr.'.rf') unless $m;  | 
| 
122
 | 
125
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
276
 | 
     if ($attr eq '#name') {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
123
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $out .= $indent.qq{  name() = }._pmltq_string($val).qq{,\n};  | 
| 
124
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       next;  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif (!$m) {  | 
| 
126
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $out .= $indent." # $attr ???;" unless $opts->{no_comments};  | 
| 
127
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       next;  | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
129
 | 
125
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
217
 | 
     my $name = $attr eq '#content' ? 'content()' : $attr;  | 
| 
130
 | 
125
 | 
  
  0
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
201
 | 
     next if $opts->{exclude} and $opts->{exclude}{$name};  | 
| 
131
 | 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
256
 | 
     $out.=member_to_pmltq($name,$val,$m,$indent.'  ',$fsfile,$opts);  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
133
 | 
15
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
68
 | 
   if (defined $opts->{rbrothers}) {  | 
| 
134
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $out .= $indent.qq{  # rbrothers()=$opts->{rbrothers},\n} unless $opts->{no_comments};  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
136
 | 
15
 | 
  
 50
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
37
 | 
   if ($opts->{connect}) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
137
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     my $rels = $opts->{connect}{$node};  | 
| 
138
 | 
15
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
36
 | 
     if ($rels) {  | 
| 
139
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
       foreach my $rel (sort keys %$rels) {  | 
| 
140
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         foreach my $n (@{$rels->{$rel}}) {  | 
| 
 
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
    | 
| 
141
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
32
 | 
         $out.='  '.$indent.$rel.' '.node_to_pmltq($n,$fsfile,{  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           %$opts,  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           indent=>$indent.'  ',  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                 }).",\n";  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($opts->{children} or $opts->{descendants}) {  | 
| 
149
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $i = 0;  | 
| 
150
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $son = $node->firstson;  | 
| 
151
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     while ($son) {  | 
| 
152
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $out.='  '.$indent.'child '.node_to_pmltq($son,$fsfile,{  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         %$opts,  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         indent=>$indent.'  ',  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         children => 0,  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         rbrothers=>$i,  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }).",\n";  | 
| 
158
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $i++;  | 
| 
159
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $son=$son->rbrother;  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
161
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $out .= $indent.qq{  # sons()=$i,\n} unless $opts->{no_comments};  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
163
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
   $out.=$indent.']';  | 
| 
164
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
175
 | 
   return $out;  | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _id_member_name {  | 
| 
169
 | 
24
 | 
 
 | 
 
 | 
  
24
  
 | 
 
 | 
117
 | 
   my ($type)=@_;  | 
| 
170
 | 
24
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
64
 | 
   return undef unless $type;  | 
| 
171
 | 
24
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
64
 | 
   if ($type->get_decl_type == PML_ELEMENT_DECL) {  | 
| 
172
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $type = $type->get_content_decl;  | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
174
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
137
 | 
   my ($omember) = $type->find_members_by_role('#ID');  | 
| 
175
 | 
24
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
4524
 | 
   if ($omember) {  | 
| 
176
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
71
 | 
     return ($omember->get_name);  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
178
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return undef; # we want this undef  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _pmltq_string {  | 
| 
182
 | 
151
 | 
 
 | 
 
 | 
  
151
  
 | 
 
 | 
226
 | 
   my ($string)=@_;  | 
| 
183
 | 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
256
 | 
   $string=~s/([\\'])/\\$1/g;  | 
| 
184
 | 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
216
 | 
   $string=~s/(\n)/\\n/g;  | 
| 
185
 | 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
450
 | 
   return qq{'$string'};  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub resolve_pmlref {  | 
| 
189
 | 
20
 | 
 
 | 
 
 | 
  
20
  
 | 
  
0
  
 | 
42
 | 
   my ($ref,$fsfile)=@_;  | 
| 
190
 | 
20
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
88
 | 
   if ($ref=~m{^(.+?)\#(.+)$}) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
191
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
     my ($file_id,$id)=($1,$2);  | 
| 
192
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
55
 | 
     my $refs = $fsfile->appData('ref');  | 
| 
193
 | 
14
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
145
 | 
     my $reffile = $refs && $refs->{$file_id};  | 
| 
194
 | 
14
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     if (UNIVERSAL::DOES::does($reffile,'Treex::PML::Document')) {  | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
195
 | 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
156
 | 
       return GetNodeByID($id,$reffile);  | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif (UNIVERSAL::DOES::does($reffile,'Treex::PML::Instance')) {  | 
| 
197
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return $reffile->lookup_id($id);  | 
| 
198
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($ref=~m{\#?([^#]+)}) {  | 
| 
200
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     return GetNodeByID($1, $fsfile);  | 
| 
201
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    return GetNodeByID($1);  | 
| 
202
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
203
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
   return undef;  | 
| 
204
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
205
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
206
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub member_to_pmltq {  | 
| 
207
 | 
210
 | 
 
 | 
 
 | 
  
210
  
 | 
  
0
  
 | 
375
 | 
   my ($name, $val, $type, $indent, $fsfile, $opts)=@_;  | 
| 
208
 | 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
220
 | 
   my $out;  | 
| 
209
 | 
210
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
425
 | 
   my $mtype = $name eq 'content()' ? $type : $type->get_knit_content_decl;  | 
| 
210
 | 
210
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
2067
 | 
   if ($mtype->get_decl_type == PML_ALT_DECL and !UNIVERSAL::DOES::does($val,'Treex::PML::Alt')) {  | 
| 
211
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
429
 | 
     $mtype = $mtype->get_knit_content_decl;  | 
| 
212
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
213
 | 
210
 | 
  
100
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
873
 | 
   if (not ref($val)) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
214
 | 
174
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
313
 | 
     if (!$mtype->is_atomic) {  | 
| 
215
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $out.=$indent."# ignoring $name\n",  | 
| 
216
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
217
 | 
174
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
480
 | 
       my $is_pmlref = (($mtype->get_decl_type == PML_CDATA_DECL) and ($mtype->get_format eq 'PMLREF')) ? 1 : 0;  | 
| 
218
 | 
174
 | 
  
100
  
 | 
  
100
  
 | 
 
 | 
 
 | 
988
 | 
       if ($type and ($type->get_role() =~ /^#(ID|ORDER)$/ or $is_pmlref)) {  | 
| 
 
 | 
 
 | 
 
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
219
 | 
53
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
667
 | 
         if ($is_pmlref and $opts->{id2name} and $val=~/(?:^.*?\#)?(.+)$/ and $opts->{id2name}{$1}) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
 50
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
220
 | 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
           $out .= $indent.qq{$name \$}.$opts->{id2name}{$1}.qq{,\n};  | 
| 
221
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif ($is_pmlref) {  | 
| 
222
 | 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
57
 | 
           my $target = resolve_pmlref($val,$fsfile);  | 
| 
223
 | 
20
 | 
  
100
  
 | 
  
 66
  
 | 
 
 | 
 
 | 
155
 | 
           if ($target && $target->type) {  | 
| 
224
 | 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
159
 | 
             $out.=$indent.'# '.$name.' '.PMLTQ::Common::DeclToQueryType( $target->type ).qq{ [ ],\n};  | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           } else {  | 
| 
226
 | 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
             $out.=$indent.'# '.$name.qq{->[ ],\n};  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           }  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } elsif ($opts->{no_comments}) {  | 
| 
229
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
           return;  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         } else {  | 
| 
231
 | 
30
 | 
 
 | 
 
 | 
 
 | 
 
 | 
96
 | 
           $out.=$indent.'# '.qq{$name = }._pmltq_string($val).qq{,\n};  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
233
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } else {  | 
| 
234
 | 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
559
 | 
         $out.=$indent;  | 
| 
235
 | 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
211
 | 
         $out.=qq{$name = }._pmltq_string($val).qq{,\n};  | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif (UNIVERSAL::DOES::does($val,'Treex::PML::List')) {  | 
| 
239
 | 
7
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
96
 | 
     if ($mtype->is_ordered) {  | 
| 
240
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
       my $i=1;  | 
| 
241
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       foreach my $v (@$val) {  | 
| 
242
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
6
 | 
         $out.=member_to_pmltq("$name/[$i]",$v,$mtype,$indent,$fsfile,$opts);  | 
| 
243
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
         $i++;  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
246
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
36
 | 
       foreach my $v (@$val) {  | 
| 
247
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
26
 | 
         $out.=member_to_pmltq($name,$v,$mtype,$indent,$fsfile,$opts);  | 
| 
248
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
249
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif (UNIVERSAL::DOES::does($val,'Treex::PML::Alt')) {  | 
| 
251
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     foreach my $v (@$val) {  | 
| 
252
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $out.=member_to_pmltq($name,$v,$mtype,$indent,$fsfile,$opts);  | 
| 
253
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
254
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif (UNIVERSAL::DOES::does($val,'Treex::PML::Struct') or UNIVERSAL::DOES::does($val,'Treex::PML::Container')) {  | 
| 
255
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1343
 | 
     $out.=$indent.qq{member $name \[\n};  | 
| 
256
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
73
 | 
     foreach my $attr ($mtype->get_normal_fields) {  | 
| 
257
 | 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4685
 | 
       my $m = $mtype->get_member_by_name($attr);  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       # next if $m and $m->get_role() eq '#ID';  | 
| 
259
 | 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1268
 | 
       my $v = $val->{$attr};  | 
| 
260
 | 
232
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
418
 | 
       next unless defined $v;  | 
| 
261
 | 
78
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
136
 | 
       $m = $mtype->get_member_by_name($attr.'.rf') unless $m;  | 
| 
262
 | 
78
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
137
 | 
       if (!$m) {  | 
| 
263
 | 
  
0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $out .= " # $attr ???;" unless $opts->{no_comments};  | 
| 
264
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         next;  | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
266
 | 
78
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
127
 | 
       my $n = $attr eq '#content' ? 'content()' : $attr;  | 
| 
267
 | 
78
 | 
  
  0
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
130
 | 
       next if $opts->{exclude} and $opts->{exclude}{$n};  | 
| 
268
 | 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
172
 | 
       $out.=member_to_pmltq($n,$v,$m,$indent.'  ',$fsfile,$opts);  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
270
 | 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
69
 | 
     $out.=$indent.qq{],\n}  | 
| 
271
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif (UNIVERSAL::DOES::does($val,'Treex::PML::Seq')) {  | 
| 
272
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $i=1;  | 
| 
273
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     foreach my $v ($val->elements) {  | 
| 
274
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my $n = $v->name;  | 
| 
275
 | 
  
0
  
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
       next if $opts->{exclude} and $opts->{exclude}{$n};  | 
| 
276
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $out.=member_to_pmltq("$name/[$i]$n",$v->value,$mtype->get_element_by_name($n),$indent,$fsfile,$opts);  | 
| 
277
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $i++;  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
280
 | 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1009
 | 
   return $out;  | 
| 
281
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
282
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
283
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
284
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #=item PML::GetNodeByID($id_or_ref,$fsfile?)  | 
| 
285
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #Looks up a node from the current file (or given fsfile) by its ID (or  | 
| 
287
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #PMLREF - i.e. the ID preceded by a file prefix of the form C).  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #=cut  | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
291
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub GetNodeByID {  | 
| 
292
 | 
18
 | 
 
 | 
 
 | 
  
18
  
 | 
  
0
  
 | 
38
 | 
     my ( $rf, $fsfile ) = @_;  | 
| 
293
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    if (!defined $fsfile) {  | 
| 
294
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #            warn("GetNodeByID TODO: FIX THIS !!!");  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         #$fsfile = $grp->{FSFile};  | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    }  | 
| 
297
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
     $rf =~ s/^.*#//;  | 
| 
298
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     return GetNodeHash($fsfile)->{$rf};  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #=item PML::GetNodeHash($fsfile?)  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #Return a reference to a hash indexing nodes in a given file (or the  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #current file if no argument is given). If such a hash was not yet  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #created, it is built upon the first call to this function (or other  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #functions calling it, such as C. Use C to  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #clear the hash.  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #=cut  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub GetNodeHash {  | 
| 
312
 | 
18
 | 
  
 50
  
 | 
 
 | 
  
18
  
 | 
  
0
  
 | 
45
 | 
     if (!ref $_[0]) {  | 
| 
313
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         shift;  | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
315
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #warn("GetNodeHash TODO: fix this:");  | 
| 
316
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #my $fsfile = $_[0] || $grp->{FSFile};  | 
| 
317
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
29
 | 
     my $fsfile = $_[0];  | 
| 
318
 | 
18
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
35
 | 
     return {} if !ref $fsfile;  | 
| 
319
 | 
18
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
44
 | 
     if ( !ref $fsfile->appData('id-hash') ) {  | 
| 
320
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my %ids;  | 
| 
321
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         my $trees = $fsfile->treeList();  | 
| 
322
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         for ( my $i = 0; $i <= $#{$trees}; $i++ ) {  | 
| 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
323
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             my $node = $trees->[$i];  | 
| 
324
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
             while ($node) {  | 
| 
325
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 weaken( $ids{ $node->{id} } = $node );  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             continue {  | 
| 
328
 | 
  
0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
                 $node = $node->following;  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
             }  | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         }  | 
| 
331
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $fsfile->changeAppData( 'id-hash', \%ids );  | 
| 
332
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
333
 | 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
129
 | 
     return $fsfile->appData('id-hash');  | 
| 
334
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  |