source: ProjectBuilder/devel/pb-modules/lib/ProjectBuilder/Conf.pm@ 1148

Last change on this file since 1148 was 1148, checked in by Bruno Cornec, 13 years ago
  • Most modules now have a VERSION declared
  • Moulde Version.pm move to pb-modules due to that
File size: 8.3 KB
RevLine 
[405]1#!/usr/bin/perl -w
2#
3# ProjectBuilder Conf module
4# Conf files subroutines brought by the the Project-Builder project
5# which can be easily used by wahtever perl project
6#
7# $Id$
8#
9
10package ProjectBuilder::Conf;
11
12use strict;
13use Data::Dumper;
14use ProjectBuilder::Base;
[1148]15use ProjectBuilder::Version;
[405]16
17# Inherit from the "Exporter" module which handles exporting functions.
18
[1148]19use vars qw($VERSION @ISA @EXPORT);
[405]20use Exporter;
21
22# Export, by default, all the functions into the namespace of
23# any code which uses this module.
24
25our @ISA = qw(Exporter);
[409]26our @EXPORT = qw(pb_conf_init pb_conf_add pb_conf_read pb_conf_read_if pb_conf_get pb_conf_get_if);
[1148]27$VERSION = "$ProjectBuilder::Version::VERSION";
[405]28
[898]29# Global hash of conf files
30# Key is the conf file name
31# Value is its rank
32my %pbconffiles;
[409]33
[898]34# Global hash of cached values.
35# We consider that values can not change during the life of pb
36# my %cachedval;
37
[405]38=pod
39
40=head1 NAME
41
42ProjectBuilder::Conf, part of the project-builder.org - module dealing with configuration files
43
44=head1 DESCRIPTION
45
46This modules provides functions dealing with configuration files.
47
48=head1 SYNOPSIS
49
50 use ProjectBuilder::Conf;
51
52 #
53 # Read hash codes of values from a configuration file and return table of pointers
54 #
55 my ($k1, $k2) = pb_conf_read_if("$ENV{'HOME'}/.pbrc","key1","key2");
56 my ($k) = pb_conf_read("$ENV{'HOME'}/.pbrc","key");
57
58=head1 USAGE
59
60=over 4
61
[505]62=item B<pb_conf_init>
63
[898]64This function setup the environment PBPROJ for project-builder function usage from other projects.
[505]65The first parameter is the project name.
[898]66It sets up environment variables (PBPROJ)
[505]67
68=cut
69
70sub pb_conf_init {
71
72my $proj=shift || undef;
73
74if (defined $proj) {
75 $ENV{'PBPROJ'} = $proj;
76} else {
77 $ENV{'PBPROJ'} = "default";
78}
79}
80
81
82
[409]83=item B<pb_conf_add>
84
85This function adds the configuration file to the list last.
86
87=cut
88
89sub pb_conf_add {
90
[415]91pb_log(2,"DEBUG: pb_conf_add with ".Dumper(@_)."\n");
[898]92
93foreach my $cf (@_) {
94 # Skip already used conf files
95 next if (defined $pbconffiles{$cf});
96 # Add the new one at the end
97 my $num = keys %pbconffiles;
[963]98 pb_log(2,"DEBUG: pb_conf_add $cf at position $num\n");
[898]99 $pbconffiles{$cf} = $num;
[1052]100 pb_log(0,"WARNING: pb_conf_add can not read $cf\n") if (! -r $cf);
[409]101}
[898]102}
[409]103
[405]104=item B<pb_conf_read_if>
105
106This function returns a table of pointers on hashes
107corresponding to the keys in a configuration file passed in parameter.
108If that file doesn't exist, it returns undef.
109
110The format of the configuration file is as follows:
111
112key tag = value1,value2,...
113
114Supposing the file is called "$ENV{'HOME'}/.pbrc", containing the following:
115
116 $ cat $HOME/.pbrc
117 pbver pb = 3
118 pbver default = 1
119 pblist pb = 12,25
120
121calling it like this:
122
123 my ($k1, $k2) = pb_conf_read_if("$ENV{'HOME'}/.pbrc","pbver","pblist");
124
125will allow to get the mapping:
126
127 $k1->{'pb'} contains 3
[409]128 $k1->{'default'} contains 1
[405]129 $k2->{'pb'} contains 12,25
130
131Valid chars for keys and tags are letters, numbers, '-' and '_'.
132
133=cut
134
135sub pb_conf_read_if {
136
137my $conffile = shift;
138my @param = @_;
139
140open(CONF,$conffile) || return((undef));
141close(CONF);
142return(pb_conf_read($conffile,@param));
143}
144
145=item B<pb_conf_read>
146
147This function is similar to B<pb_conf_read_if> except that it dies when the file in parameter doesn't exist.
148
149=cut
150
151sub pb_conf_read {
152
153my $conffile = shift;
154my @param = @_;
155my $trace;
156my @ptr;
157my %h;
158
159open(CONF,$conffile) || die "Unable to open $conffile";
160while(<CONF>) {
[638]161 if (/^\s*([A-z0-9-_.]+)\s+([[A-z0-9-_.]+)\s*=\s*(.+)$/) {
[405]162 pb_log(3,"DEBUG: 1:$1 2:$2 3:$3\n");
163 $h{$1}{$2}=$3;
164 }
165}
166close(CONF);
167
168for my $param (@param) {
169 push @ptr,$h{$param};
170}
171return(@ptr);
172}
173
[409]174=item B<pb_conf_get_if>
[405]175
[963]176This function returns a table, corresponding to a set of values queried in the conf files or undef if it doen't exist. It takes a table of keys as an input parameter.
[405]177
[409]178The format of the configurations file is as follows:
179
180key tag = value1,value2,...
181
[505]182It will gather the values from all the configurations files passed to pb_conf_add, and return the values for the keys, taking in account the order of conf files, to manage overloading.
[409]183
184 $ cat $HOME/.pbrc
185 pbver pb = 1
186 pblist pb = 4
187 $ cat $HOME/.pbrc2
188 pbver pb = 3
189 pblist default = 5
190
191calling it like this:
192
[505]193 pb_conf_add("$HOME/.pbrc","$HOME/.pbrc2");
[409]194 my ($k1, $k2) = pb_conf_get_if("pbver","pblist");
195
196will allow to get the mapping:
197
198 $k1->{'pb'} contains 3
199 $k2->{'pb'} contains 4
200
201Valid chars for keys and tags are letters, numbers, '-' and '_'.
202
203=cut
204
205sub pb_conf_get_if {
206
[405]207my @param = @_;
208
[409]209my $ptr = undef;
[405]210
[898]211# the most important conf file is first, so read them in reverse order
212foreach my $f (reverse sort { $pbconffiles{$a} <=> $pbconffiles{$b} } keys %pbconffiles) {
[963]213 pb_log(2,"DEBUG: pb_conf_get_if in file $f\n");
[409]214 $ptr = pb_conf_get_fromfile_if("$f",$ptr,@param);
[405]215}
[409]216
217return(@$ptr);
[405]218}
219
[409]220=item B<pb_conf_fromfile_if>
[405]221
[1027]222This function returns a pointer on a table, corresponding to a merge of values queried in the conf file and the pointer on another table passed as parameter. It takes a table of keys as last input parameter.
[409]223
224 my ($k1) = pb_conf_fromfile_if("$HOME/.pbrc",undef,"pbver","pblist");
225 my ($k2) = pb_conf_fromfile_if("$HOME/.pbrc3",$k1,"pbver","pblist");
226
227It is used internally by pb_conf_get_if and is not exported yet.
228
229=cut
230
231
232sub pb_conf_get_fromfile_if {
233
234my $conffile = shift;
235my $ptr2 = shift || undef;
[405]236my @param = @_;
237
238# Everything is returned via ptr1
239my @ptr1 = ();
240my @ptr2 = ();
241
[409]242# @ptr1 contains the values overloading what @ptr2 may contain.
243@ptr1 = pb_conf_read_if("$conffile", @param) if (defined $conffile);
244@ptr2 = @$ptr2 if (defined $ptr2);
245
[405]246my $p1;
247my $p2;
248
[963]249pb_log(2,"DEBUG: pb_conf_get_from_file $conffile: ".Dumper(@ptr1)."\n");
250pb_log(2,"DEBUG: pb_conf_get_from_file input: ".Dumper(@ptr2)."\n");
251pb_log(2,"DEBUG: pb_conf_get_from_file param: ".Dumper(@param)."\n");
[405]252
253foreach my $i (0..$#param) {
254 $p1 = $ptr1[$i];
[898]255 # Optimisation doesn't seem useful
256 # if ((defined $p1) && (defined $cachedval{$p1})) {
257 # $ptr1[$i] = $cachedval{$p1};
258 # next;
259 # }
[405]260 $p2 = $ptr2[$i];
[409]261 # Always try to take the param from ptr1
262 # in order to mask what could be defined already in ptr2
[405]263 if (not defined $p2) {
[415]264 # exit if no p1 either
[424]265 next if ((not defined $p1) || (not defined $ENV{'PBPROJ'}));
[409]266 # No ref in p2 so use p1
[405]267 $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if ((not defined $p1->{$ENV{'PBPROJ'}}) && (defined $p1->{'default'}));
268 } else {
[409]269 # Ref found in p2
[405]270 if (not defined $p1) {
[409]271 # No ref in p1 so use p2's value
[405]272 $p2->{$ENV{'PBPROJ'}} = $p2->{'default'} if ((not defined $p2->{$ENV{'PBPROJ'}}) && (defined $p2->{'default'}));
273 $p1 = $p2;
274 } else {
275 # Both are defined - handling the overloading
276 if (not defined $p1->{'default'}) {
277 if (defined $p2->{'default'}) {
278 $p1->{'default'} = $p2->{'default'};
279 }
280 }
281
282 if (not defined $p1->{$ENV{'PBPROJ'}}) {
283 if (defined $p2->{$ENV{'PBPROJ'}}) {
284 $p1->{$ENV{'PBPROJ'}} = $p2->{$ENV{'PBPROJ'}} if (defined $p2->{$ENV{'PBPROJ'}});
285 } else {
286 $p1->{$ENV{'PBPROJ'}} = $p1->{'default'} if (defined $p1->{'default'});
287 }
288 }
289 # Now copy back into p1 all p2 content which doesn't exist in p1
[409]290 # p1 content always has priority over p2
[405]291 foreach my $k (keys %$p2) {
292 $p1->{$k} = $p2->{$k} if (not defined $p1->{$k});
293 }
294 }
295 }
296 $ptr1[$i] = $p1;
[898]297 # Cache values to avoid redoing all that analyze when asked again on a known value
298 # $cachedval{$p1} = $p1;
[405]299}
[415]300pb_log(2,"DEBUG: pb_conf_get output: ".Dumper(@ptr1)."\n");
[409]301return(\@ptr1);
[405]302}
303
[409]304=item B<pb_conf_get>
[405]305
[409]306This function is the same B<pb_conf_get_if>, except that it tests each returned value as they need to exist in that case.
307
308=cut
309
310sub pb_conf_get {
311
312my @param = @_;
313my @return = pb_conf_get_if(@param);
[932]314my $proj = undef;
[409]315
[932]316if (not defined $ENV{'PBPROJ'}) {
317 $proj = "unknown";
318} else {
319 $proj = $ENV{'PBPROJ'};
320}
[409]321
[932]322die "No params found for $proj" if (not @return);
323
[409]324foreach my $i (0..$#param) {
[932]325 die "No $param[$i] defined for $proj" if (not defined $return[$i]);
[409]326}
327return(@return);
328}
329
[405]330=back
331
332=head1 WEB SITES
333
334The main Web site of the project is available at L<http://www.project-builder.org/>. Bug reports should be filled using the trac instance of the project at L<http://trac.project-builder.org/>.
335
336=head1 USER MAILING LIST
337
338None exists for the moment.
339
340=head1 AUTHORS
341
342The Project-Builder.org team L<http://trac.project-builder.org/> lead by Bruno Cornec L<mailto:bruno@project-builder.org>.
343
344=head1 COPYRIGHT
345
346Project-Builder.org is distributed under the GPL v2.0 license
347described in the file C<COPYING> included with the distribution.
348
349=cut
350
351
3521;
Note: See TracBrowser for help on using the repository browser.