File Coverage

blib/lib/Tie/Config.pm
Criterion Covered Total %
statement 76 80 95.0
branch 23 36 63.8
condition 7 11 63.6
subroutine 12 12 100.0
pod n/a
total 118 139 84.8


line stmt bran cond sub pod time code
1             ##############################################################################
2             #
3             # Copyright (c) 2001-2002 Jan 'Kozo' Vajda
4             # All rights reserved.
5             #
6             ##############################################################################
7              
8             package Tie::Config;
9              
10 6     6   4404 use Exporter;
  6         11  
  6         276  
11              
12 6     6   30 use strict;
  6         8  
  6         216  
13 6     6   25 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK $AUTOLOAD);
  6         14  
  6         547  
14 6     6   26 use Carp;
  6         15  
  6         551  
15 6     6   5956 use IO::File;
  6         77630  
  6         867  
16 6     6   6417 use Tie::Hash;
  6         6213  
  6         178  
17 6     6   39 use Fcntl;
  6         15  
  6         2811  
18 6     6   7024 use Data::Dumper;
  6         78212  
  6         9005  
19              
20             @ISA = qw(Tie::StdHash);
21              
22             $VERSION = '0.04';
23              
24             # Items to export into callers namespace by default
25             @EXPORT = qw();
26              
27             # Other items we are prepared to export if requested
28             @EXPORT_OK = qw();
29              
30             =head1 NAME
31              
32             Tie::Config - class definitions for tied hashes config file reading
33              
34             =head1 SYNOPSIS
35              
36             use Tie::Config;
37            
38             tie %hash, 'Tie::Config', ".foo_rc", O_RDWR;
39            
40            
41             =head1 DESCRIPTION
42              
43             Tied config file reader
44              
45             =head1 USE
46              
47             use Tie::Config;
48            
49             tie %hash, 'Tie::Config', ".foo_rc", O_RDWR;
50            
51             print $hash{'key'};
52             $hash{'key'} = "newvalue";
53            
54             untie %hash;
55              
56             Comments is handled internal and is wroted at the top of the file.
57             If ommited access mode default is O_RDONLY ( read only access ).
58             Currently supported mode is only O_RDONLY and O_RDWR.
59              
60             If config file is changed between tie and untie by other proces, any changes
61             will be lost.
62            
63             =cut
64              
65             sub TIEHASH {
66 6     6   867 my $class = shift;
67 6         14 my $file = shift;
68 6   100     44 my $access = shift || O_RDONLY ;
69              
70 6         13 my $hash = {};
71 6         18 bless $hash, $class;
72              
73 6         53 $hash->{_internal_filename} = $file;
74 6         19 $hash->{_internal_accessmode} = $access;
75            
76 6 50       150 carp("File ".$hash->{_internal_filename}." does not exist.") unless ( -f $hash->{_internal_filename});
77              
78 6 50       141 my $rc = IO::File->new($hash->{_internal_filename}, O_RDONLY) if ( -f $hash->{_internal_filename} );
79 6 50       676 if ( defined $rc ) {
80              
81 6         14 my $separator = '\s*=\s*';
82            
83             ### pre istotu vymazem komentare
84 6         19 $hash->{_internal_comments} = '';
85              
86 6         160 while (<$rc>) {
87 48         85 chomp;
88             #### Skip blank text entry fields
89 48 100       220 next if ( /^\s*$/o );
90             ### get comments
91 44 100 100     232 if ( /^\s*#/o || /^\s*\;/o) {
92             ### pridam do pola komentarov
93 10         32 $hash->{_internal_comments} .= $_ . "\n";
94 10         35 next;
95             }
96             ### Skip unless contain separator
97 34 50       250 next unless ( /${separator}/o );
98              
99 34         488 my ($key,$value) = /\s*(.*?)${separator}(.*?)\s*$/o;
100 34         125 my $length = length($value);
101              
102             ### skip empty keys
103 34 50 33     120 next if ( !$length || !$key );
104            
105 34         182 $hash->{$key} = $value;
106             }
107              
108 6         60 $rc->close;
109              
110             } else {
111 0         0 carp("Canot open file ".$hash->{_internal_filename});
112             }
113              
114 6         124 $hash;
115             }
116              
117             sub STORE {
118 3     3   3748 my ($self, $key, $val) = @_;
119              
120             # print STDERR "$self, $key, $val\n";
121            
122 3 50       18 if ( $key =~ /^_internal/o ) {
123 0         0 carp "invalid key [$key] in hash";
124 0         0 return;
125             }
126              
127 3 100       14 if ( !$self->{_internal_accessmode} ) {
128 1         254 carp "hash is read only";
129 1         129 return;
130             }
131            
132 2 50 33     11 return($val) if ( defined $self->{$key} && $self->{$key} eq $val);
133 2         37 $self->{_internal_changed} = '1';
134            
135             # print STDERR "hash content changed\n";
136            
137 2         114 $self->{$key} = $val;
138             }
139              
140             sub DESTROY {
141 1     1   13 my $self = shift;
142 1         2 my ($key,$value);
143            
144             # print STDERR "Destroyed\n";
145             # print STDERR Data::Dumper->Dump([$self],[qw(*destroyed)]);
146              
147             ### is read only
148 1 50       4 return() unless ($self->{_internal_accessmode});
149              
150             ### is changed
151 1 50       5 return() unless ($self->{_internal_changed});
152            
153             # print STDERR "untied\n";
154              
155 1         8 my $rc = new IO::File $self->{_internal_filename}, O_CREAT|O_WRONLY|O_TRUNC;
156 1 50       162 if ( defined $rc ) {
157            
158             ### zapiseme komentare ak existuju
159 1 50       5 print $rc $self->{_internal_comments} if $self->{_internal_comments};
160            
161 1         2 my $separator = ' = ';
162              
163 1         1 while (($key,$value) = each %{$self}) {
  5         17  
164 4 100       30 print $rc "$key${separator}$value\n" unless ($key =~ /^_internal/o);
165             }
166 1         6 $rc->close;
167 1 50       64 carp "Can't close file ".$self->{_internal_filename} .": $1" if $?;
168             } else {
169 0         0 carp "Can't open ".$self->{_internal_filename};
170             }
171             }
172              
173             sub CLEAR {
174 1     1   265 my $self = shift;
175 1         2 my ($key,$value);
176              
177             # print STDERR "CLEAR !!\n";
178              
179 1         2 while (($key,$value) = each %{$self}) {
  11         35  
180 10 100       56 delete $self->{$key} unless ($key =~ /^_internal/o);
181             }
182 1 50       10 delete $self->{_internal_comments} if $self->{_internal_comments};
183             }
184              
185             #sub AUTOLOAD {
186             # my $self = shift;
187             # my $value = shift;
188             # my ($name) = $AUTOLOAD;
189             #
190             # ($name) = ( $name =~ /^.*::(.*)/);
191             #
192             # $self->{$name} = $value if ( defined $value );
193             #
194             # return($self->{$name});
195             #
196             #}
197              
198             ### set True
199             3.14;
200              
201             __END__