File Coverage

blib/lib/Text/TreeFile.pm
Criterion Covered Total %
statement 9 98 9.1
branch 0 52 0.0
condition 0 30 0.0
subroutine 3 6 50.0
pod 0 1 0.0
total 12 187 6.4


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__