line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# file: Text/TreeFile.pm |
2
|
|
|
|
|
|
|
# |
3
|
|
|
|
|
|
|
# Copyright (c) 2000 John Kirk. All rights reserved. |
4
|
|
|
|
|
|
|
# This program is free software; you can redistribute it and/or |
5
|
|
|
|
|
|
|
# modify it under the same terms as Perl itself. |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# The latest version of this module should always be available |
8
|
|
|
|
|
|
|
# at any CPAN (http://www.cpan.org) mirror, or from the author: |
9
|
|
|
|
|
|
|
# http://perl.dystanhays.com/jnk |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
package Text::TreeFile; |
12
|
|
|
|
|
|
|
|
13
|
1
|
|
|
1
|
|
1633
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
84
|
|
14
|
1
|
|
|
1
|
|
6
|
use vars qw($VERSION @ISA @EXPORT_OK); |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
200
|
|
15
|
|
|
|
|
|
|
|
16
|
|
|
|
|
|
|
require Exporter; |
17
|
|
|
|
|
|
|
require AutoLoader; |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
$VERSION=0.39; |
20
|
|
|
|
|
|
|
@ISA=qw(Exporter AutoLoader); |
21
|
|
|
|
|
|
|
@EXPORT_OK=qw(showlines showglobals); |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
require 5.002; |
24
|
1
|
|
|
1
|
|
1424
|
use FileHandle; # nice to easily have filehandles as plain variables |
|
1
|
|
|
|
|
18957
|
|
|
1
|
|
|
|
|
6
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
my %proto=( 'endq'=>undef,'top'=>undef,'idir'=>undef,'iname'=>undef, |
27
|
|
|
|
|
|
|
'nest'=>undef,'level'=>undef,'line'=>undef,'lev'=>undef, ); |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub _loadtree; |
30
|
|
|
|
|
|
|
sub _readspec; |
31
|
|
|
|
|
|
|
sub showlines; |
32
|
|
|
|
|
|
|
sub showglobals; |
33
|
|
|
|
|
|
|
|
34
|
0
|
|
|
0
|
0
|
|
sub new { my ($that,$iname,$endq)=@_; |
35
|
0
|
|
0
|
|
|
|
my $class=ref($that)||$that; |
36
|
0
|
|
|
|
|
|
my $me={_prop=>\%proto,%proto,}; |
37
|
0
|
|
|
|
|
|
bless $me,$class; |
38
|
0
|
0
|
|
|
|
|
if(defined $endq) { $$me{endq}=$endq; } |
|
0
|
|
|
|
|
|
|
39
|
0
|
0
|
|
|
|
|
if(defined $iname) { $$me{iname}=$iname; |
|
0
|
|
|
|
|
|
|
40
|
0
|
|
|
|
|
|
$iname=~/^(.*\/)([^\/]*)$/; |
41
|
0
|
0
|
0
|
|
|
|
$$me{idir}=(defined $1 and $1 ne '')?$1:''; |
42
|
0
|
0
|
|
|
|
|
$$me{top}=_loadtree $me or return undef; |
43
|
|
|
|
|
|
|
} |
44
|
0
|
|
|
|
|
|
return $me; |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
0
|
|
|
0
|
|
|
sub _loadtree { my $me=shift; |
48
|
0
|
|
|
|
|
|
my ($spec,$cnt); |
49
|
0
|
0
|
|
|
|
|
if(!defined $$me{nest}) { |
50
|
0
|
|
|
|
|
|
$$me{nest}=0; |
51
|
0
|
|
|
|
|
|
$$me{lev}=[{'cum'=>0,'lev'=>0,'ifn'=>undef,'ifh'=>undef,'ifl'=>undef,}]; |
52
|
0
|
0
|
|
|
|
|
if(defined $$me{endq}) { |
53
|
0
|
|
|
|
|
|
$spec=[]; |
54
|
0
|
|
|
|
|
|
$cnt=0; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
} |
57
|
0
|
|
|
|
|
|
my $lp=$$me{lev}[$$me{nest}]; |
58
|
0
|
0
|
0
|
|
|
|
if((!defined $$lp{ifh})&&($$me{nest}==0)) { |
59
|
0
|
0
|
0
|
|
|
|
if(exists $$me{iname} and defined $$me{iname}) { |
60
|
0
|
|
|
|
|
|
$$lp{ifn}=$$me{iname}; |
61
|
|
|
|
|
|
|
} else { |
62
|
0
|
|
|
|
|
|
print "_loadtree(): wasn't given a filename at the top file nesting level\n"; |
63
|
0
|
|
|
|
|
|
return undef; |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
} |
66
|
0
|
0
|
|
|
|
|
if(!defined $$lp{ifn}) { |
|
|
0
|
|
|
|
|
|
67
|
0
|
|
|
|
|
|
print "_loadtree() got no input filename at file nesting level $$me{nest}\n"; |
68
|
0
|
|
|
|
|
|
return undef; |
69
|
|
|
|
|
|
|
} elsif(!defined $$lp{ifh}) { |
70
|
0
|
|
|
|
|
|
$$lp{ifh}=new FileHandle "<$$lp{ifn}"; |
71
|
0
|
|
|
|
|
|
$$me{line}=undef; |
72
|
|
|
|
|
|
|
} |
73
|
0
|
0
|
|
|
|
|
if(!defined $$lp{ifh}) { |
74
|
0
|
|
|
|
|
|
print "_loadtree() couldn't open ifile: $$lp{ifn}\n"; |
75
|
0
|
|
|
|
|
|
return undef; |
76
|
|
|
|
|
|
|
} |
77
|
0
|
0
|
|
|
|
|
if(!defined $$me{line}) { |
78
|
0
|
|
|
|
|
|
($$me{level},$$me{line})=_readspec $$lp{ifh},$$lp{ifl}; |
79
|
|
|
|
|
|
|
} |
80
|
0
|
|
|
|
|
|
while(defined $$me{line}) { # loop on top-level specs; test eof from readspec |
81
|
0
|
0
|
|
|
|
|
if($$me{line}=~/^include\s+(\S+)/) { |
82
|
0
|
|
|
|
|
|
my $iname="$$me{idir}$1"; |
83
|
0
|
|
|
|
|
|
my ($cum,$lev)=($$me{lev}[$$me{nest}]{cum},$$me{lev}[$$me{nest}]{lev}); |
84
|
0
|
|
|
|
|
|
++$$me{nest}; |
85
|
0
|
|
|
|
|
|
$$me{lev}[$$me{nest}]={ |
86
|
|
|
|
|
|
|
'cum'=>$cum+$lev,'lev'=>0,'ifn'=>$iname,'ifh'=>undef,'ifl'=>undef, |
87
|
|
|
|
|
|
|
}; |
88
|
0
|
0
|
|
|
|
|
if(defined $cnt) { $$spec[$cnt++]=_loadtree($me); } |
|
0
|
|
|
|
|
|
|
89
|
0
|
|
|
|
|
|
else { $spec =_loadtree($me); } |
90
|
|
|
|
|
|
|
|
91
|
0
|
|
|
|
|
|
--$$me{nest}; |
92
|
0
|
|
|
|
|
|
($$me{level},$$me{line})=_readspec $$lp{ifh},$$lp{ifl}; |
93
|
|
|
|
|
|
|
} else { |
94
|
0
|
|
|
|
|
|
my @specs=(); |
95
|
0
|
0
|
|
|
|
|
if(defined $cnt) { $$spec[$cnt++]=[$$me{line},\@specs]; } |
|
0
|
|
|
|
|
|
|
96
|
0
|
|
|
|
|
|
else { $spec =[$$me{line},\@specs]; } |
97
|
0
|
|
|
|
|
|
($$me{level},$$me{line})=_readspec $$lp{ifh},$$lp{ifl}; |
98
|
0
|
|
|
|
|
|
my $sublevel=(++$$lp{lev}); |
99
|
0
|
|
0
|
|
|
|
while((defined $$me{level}) && ($$me{level}==$sublevel)) { |
100
|
0
|
|
|
|
|
|
push @specs,_loadtree($me); |
101
|
|
|
|
|
|
|
} |
102
|
0
|
|
|
|
|
|
--$$lp{lev}; |
103
|
|
|
|
|
|
|
} |
104
|
0
|
0
|
|
|
|
|
last if(!defined $cnt); |
105
|
|
|
|
|
|
|
} |
106
|
0
|
|
|
|
|
|
return $spec; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
0
|
|
|
0
|
|
|
sub _readspec { my $ifh=shift; |
110
|
0
|
0
|
|
|
|
|
if(!defined $_[0]) { |
111
|
0
|
|
|
|
|
|
while(<$ifh>) { # this is the first line of a file |
112
|
0
|
0
|
0
|
|
|
|
next if(/^exec\s/ or /^[#;\/]/ or /^\s*\.\.\./ or /^\s*$/); |
|
|
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
113
|
0
|
|
|
|
|
|
last; |
114
|
|
|
|
|
|
|
} |
115
|
0
|
0
|
|
|
|
|
if(eof($ifh)) { |
116
|
0
|
|
|
|
|
|
$_[0]=''; |
117
|
0
|
|
|
|
|
|
return (0,undef); |
118
|
|
|
|
|
|
|
} |
119
|
0
|
|
|
|
|
|
chop; |
120
|
0
|
|
|
|
|
|
$_[0]=$_; |
121
|
|
|
|
|
|
|
} |
122
|
0
|
0
|
|
|
|
|
if(!defined $_[0]) { |
123
|
0
|
|
|
|
|
|
return (undef,undef); |
124
|
|
|
|
|
|
|
} |
125
|
0
|
0
|
|
|
|
|
if($_[0] eq '') { |
126
|
0
|
|
|
|
|
|
return (0,undef); |
127
|
|
|
|
|
|
|
} |
128
|
0
|
|
|
|
|
|
my ($indent,$line,$str); |
129
|
0
|
|
|
|
|
|
($indent,$line)=$_[0]=~/^([ ]*)(.*)$/; |
130
|
0
|
|
|
|
|
|
my $level=length($indent)/2; |
131
|
0
|
0
|
|
|
|
|
die "indent. not a mult. of two spaces\n" if($level*2!=length($indent)); |
132
|
0
|
|
|
|
|
|
while(<$ifh>) { |
133
|
0
|
0
|
0
|
|
|
|
next if(/^[#;]/ or /^\s*\.\.\.\s*$/ or /^\s*$/); |
|
|
|
0
|
|
|
|
|
134
|
0
|
|
|
|
|
|
chop; |
135
|
0
|
|
|
|
|
|
($indent,$str)=/^(\s*)\.\.\.(.*)$/; |
136
|
0
|
0
|
|
|
|
|
if(defined $str) { |
137
|
0
|
|
|
|
|
|
$str=~s/^\s+/\ /; |
138
|
0
|
|
|
|
|
|
$line.=$str; |
139
|
0
|
|
|
|
|
|
next; |
140
|
|
|
|
|
|
|
} |
141
|
0
|
|
|
|
|
|
$_[0]=$_; |
142
|
0
|
|
|
|
|
|
last; |
143
|
|
|
|
|
|
|
} |
144
|
0
|
0
|
|
|
|
|
if(eof($ifh)) { |
145
|
0
|
0
|
|
|
|
|
$_[0]='' if(!defined $_); |
146
|
|
|
|
|
|
|
} |
147
|
0
|
|
|
|
|
|
return ($level,$line); |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
1; |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
__END__ |