ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/BuildFile.pm
Revision: 1.35
Committed: Mon Feb 13 16:12:39 2012 UTC (13 years, 2 months ago) by muzaffar
Content type: text/plain
Branch: MAIN
Changes since 1.34: +25 -62 lines
Log Message:
improved arch section for BuildFile. Now one can have nasted arch section

File Contents

# Content
1 #____________________________________________________________________
2 # File: BuildFile.pm
3 #____________________________________________________________________
4 #
5 # Author: Shaun Ashby <Shaun.Ashby@cern.ch>
6 # Copyright: 2003 (C) Shaun Ashby
7 #
8 #--------------------------------------------------------------------
9 package BuildSystem::BuildFile;
10 require 5.004;
11 use Exporter;
12 use ActiveDoc::SimpleDoc;
13
14 @ISA=qw(Exporter);
15 @EXPORT_OK=qw( );
16 #
17 sub new()
18 ###############################################################
19 # new #
20 ###############################################################
21 # modified : Wed Dec 3 19:03:22 2003 / SFA #
22 # params : #
23 # : #
24 # function : #
25 # : #
26 ###############################################################
27 {
28 my $proto=shift;
29 my $class=ref($proto) || $proto;
30 $self={};
31 bless $self,$class;
32 $self->{DEPENDENCIES} = {};
33 $self->{content} = {};
34 $self->{scramdoc}=ActiveDoc::SimpleDoc->new();
35 $self->{scramdoc}->newparse("builder",__PACKAGE__,'Subs',shift);
36 $self->{archs}=[];
37 $self->{archflag}=1;
38 return $self;
39 }
40
41 sub parse()
42 {
43 my $self=shift;
44 my ($filename)=@_;
45 my $fhead='<?xml version="1.0" encoding="UTF-8" standalone="yes"?><doc type="BuildSystem::BuildFile" version="1.0">';
46 my $ftail='</doc>';
47 $self->{scramdoc}->filetoparse($filename);
48 $self->{scramdoc}->parse("builder",$fhead,$ftail);
49 # We're done with the SimpleDoc object so delete it:
50 delete $self->{scramdoc};
51 }
52
53 sub classpath()
54 {
55 my ($object,$name,%attributes)=@_;
56 # The getter part:
57 if (ref($object) eq __PACKAGE__)
58 {
59 return $self->{content}->{CLASSPATH};
60 }
61 if (!$self->{archflag}){return;}
62 $self->{nested} == 1 ? push(@{$self->{tagcontent}->{CLASSPATH}}, $attributes{'path'})
63 : push(@{$self->{content}->{CLASSPATH}}, $attributes{'path'});
64 }
65
66 sub productstore()
67 {
68 my ($object,$name,%attributes)=@_;
69 # The getter part:
70 if (ref($object) eq __PACKAGE__)
71 {
72 # Return an array of ProductStore hashes:
73 return $self->{content}->{PRODUCTSTORE};
74 }
75 if (!$self->{archflag}){return;}
76 $self->{nested} == 1 ? push(@{$self->{tagcontent}->{PRODUCTSTORE}}, \%attributes)
77 : push(@{$self->{content}->{PRODUCTSTORE}}, \%attributes) ;
78 }
79
80 sub include()
81 {
82 my $self=shift;
83 # Return an array of required includes:
84 return $self->{content}->{INCLUDE};
85 }
86
87 sub include_path()
88 {
89 my ($object,$name,%attributes)=@_;
90 if (!$self->{archflag}){return;}
91 $self->{nested} == 1 ? push(@{$self->{tagcontent}->{INCLUDE}}, $attributes{'path'})
92 : push(@{$self->{content}->{INCLUDE}}, $attributes{'path'});
93 }
94
95 sub use()
96 {
97 my $object=shift;
98 # The getter part:
99 if (ref($object) eq __PACKAGE__)
100 {
101 # Add or return uses (package deps):
102 @_ ? push(@{$self->{content}->{USE}},@_)
103 : @{$self->{content}->{USE}};
104 }
105 else
106 {
107 if (!$self->{archflag}){return;}
108 my ($name,%attributes)=@_;
109 $self->{DEPENDENCIES}->{$attributes{'name'}} = 1;
110 $self->{nested} == 1 ? push(@{$self->{tagcontent}->{USE}}, $attributes{'name'})
111 : push(@{$self->{content}->{USE}}, $attributes{'name'});
112 }
113 }
114
115 sub architecture()
116 {
117 my ($object,$name,%attributes)=@_;
118 my $flag=$self->{archflag};
119 push @{$self->{archs}},$flag;
120 my $arch=$attributes{name};
121 if (($flag) && ($ENV{SCRAM_ARCH}!~/$arch/)){$self->{archflag}=0;}
122 }
123
124 sub architecture_()
125 {
126 my ($object,$name,%attributes)=@_;
127 $self->{archflag}=pop @{$self->{archs}};
128 }
129
130 sub export()
131 {
132 my ($object,$name,%attributes)=@_;
133 if (!$self->{archflag}){return;}
134 $self->pushlevel(); # Set nested to 1;
135 }
136
137 sub export_()
138 {
139 my ($object,$name,%attributes)=@_;
140 if (!$self->{archflag}){return;}
141 $self->{content}->{EXPORT} = $self->{tagcontent};
142 $self->poplevel();
143 }
144
145 sub lib()
146 {
147 my ($object,$name,%attributes)=@_;
148 # The getter part:
149 if (ref($object) eq __PACKAGE__)
150 {
151 # Return an array of required libs:
152 return $self->{content}->{LIB};
153 }
154 if (!$self->{archflag}){return;}
155 my $libname;
156
157 if (exists($attributes{'position'}))
158 {
159 if ($attributes{'position'} eq 'first')
160 {
161 $libname = "F:".$attributes{'name'};
162 }
163 else
164 {
165 # There was a position entry but it didn't make sense:
166 $libname = $attributes{'name'};
167 }
168 }
169 else
170 {
171 $libname = $attributes{'name'};
172 }
173 # We have a libname, add it to the list:
174 $self->{nested} == 1 ? push(@{$self->{tagcontent}->{LIB}}, $libname)
175 : push(@{$self->{content}->{LIB}}, $libname);
176 }
177
178 sub makefile()
179 {
180 my ($object,$name,%attributes)=@_;
181 # The getter part:
182 if (ref($object) eq __PACKAGE__)
183 {
184 return $self->{content}->{MAKEFILE};
185 }
186 }
187
188 sub makefile_()
189 {
190 my ($object,$name,$cdata)=@_;
191 if (!$self->{archflag}){return;}
192 $self->{nested} == 1 ? push(@{$self->{tagcontent}->{MAKEFILE}}, join("\n",@$cdata))
193 : push(@{$self->{content}->{MAKEFILE}}, join("\n",@$cdata));
194 }
195
196 sub flags()
197 {
198 my ($object,$name,%attributes)=@_;
199 # The getter part:
200 if (ref($object) eq __PACKAGE__)
201 {
202 # Return an array of ProductStore hashes:
203 return $self->{content}->{FLAGS};
204 }
205 if (!$self->{archflag}){return;}
206 # Extract the flag name and its value:
207 my ($flagname,$flagvaluestring) = each %attributes;
208 $flagname =~ tr/[a-z]/[A-Z]/; # Keep flag name uppercase
209 chomp($flagvaluestring);
210 my @flagvalues = ( $flagvaluestring );
211 # Is current tag within another tag block?
212 if ($self->{nested} == 1)
213 {
214 # Check to see if the current flag name is already stored in the hash. If so,
215 # just add the new values to the array of flag values:
216 if (exists ($self->{tagcontent}->{FLAGS}->{$flagname}))
217 {
218 push(@{$self->{tagcontent}->{FLAGS}->{$flagname}},@flagvalues);
219 }
220 else
221 {
222 $self->{tagcontent}->{FLAGS}->{$flagname} = [ @flagvalues ];
223 }
224 }
225 else
226 {
227 if (exists ($self->{content}->{FLAGS}->{$flagname}))
228 {
229 push(@{$self->{content}->{FLAGS}->{$flagname}},@flagvalues);
230 }
231 else
232 {
233 $self->{content}->{FLAGS}->{$flagname} = [ @flagvalues ];
234 }
235 }
236 }
237
238 sub allflags()
239 {
240 my $self=shift;
241 # Return hash data for flags:
242 return $self->{content}->{FLAGS};
243 }
244
245 sub bin()
246 {
247 my ($object,$name,%attributes) = @_;
248 if (!$self->{archflag}){return;}
249 $self->pushlevel(\%attributes);# Set nested to 1;
250 }
251
252 sub bin_()
253 {
254 my ($object,$name,%attributes) = @_;
255 if (!$self->{archflag}){return;}
256 # Need unique name for the binary (always use name of product). Either use "name"
257 # given, or use "file" value minus the ending:
258 if (exists ($self->{id}->{'name'}))
259 {
260 $name = $self->{id}->{'name'};
261 }
262 else
263 {
264 ($name) = ($self->{id}->{'file'} =~ /(.*)?\..*$/);
265 }
266
267 # Store the data:
268 $self->productcollector($name,'bin','BIN');
269 $self->poplevel();
270 }
271
272 sub library()
273 {
274 my ($object,$name,%attributes) = @_;
275 if (!$self->{archflag}){return;}
276 $self->pushlevel(\%attributes);# Set nested to 1;
277 }
278
279 sub library_()
280 {
281 my ($object,$name,%attributes) = @_;
282 if (!$self->{archflag}){return;}
283 # Need unique name for the library (always use name of product). Either use "name"
284 # given, or use "file" value minus the ending:
285 if (exists ($self->{id}->{'name'}))
286 {
287 $name = $self->{id}->{'name'};
288 }
289 else
290 {
291 ($name) = ($self->{id}->{'file'} =~ /(.*)?\..*$/);
292 }
293
294 # Store the data:
295 $self->productcollector($name,'lib','LIBRARY');
296 $self->poplevel();
297 }
298
299 sub productcollector()
300 {
301 my $self=shift;
302 my ($name,$typeshort,$typefull)=@_;
303 # Create a new Product object for storage of data:
304 use BuildSystem::Product;
305 my $product = BuildSystem::Product->new();
306 # Store the name:
307 $product->name($name);
308 $product->type($typeshort);
309 # Store the files. Take the BuildFile path as the initial path for
310 # expanding source file globs:
311 $product->_files($self->{id}->{'file'},[ $self->{scramdoc}->filetoparse() ]);
312 # Store the data content:
313 $product->_data($self->{tagcontent});
314 # And store in a hash (all build products in same place):
315 $self->{content}->{BUILDPRODUCTS}->{$typefull}->{$name} = $product;
316 }
317
318 sub pushlevel
319 {
320 my $self = shift;
321 my ($info)=@_;
322
323 $self->{id} = $info if (defined $info);
324 $self->{nested} = 1;
325 $self->{tagcontent}={};
326 }
327
328 sub poplevel
329 {
330 my $self = shift;
331 delete $self->{id};
332 delete $self->{nested};
333 delete $self->{tagcontent};
334 }
335
336 sub dependencies()
337 {
338 my $self=shift;
339 # Make a copy of the variable so that
340 # we don't have a DEPENDENCIES entry in RAWDATA:
341 my %DEPS=%{$self->{DEPENDENCIES}};
342 delete $self->{DEPENDENCIES};
343 return \%DEPS;
344 }
345
346 sub skippeddirs()
347 {
348 my $self=shift;
349 my ($here)=@_;
350 my $skipped;
351
352 if ($self->{content}->{SKIPPEDDIRS}->[0] == 1)
353 {
354 $skipped = [ @{$self->{content}->{SKIPPEDDIRS}} ];
355 delete $self->{content}->{SKIPPEDDIRS};
356 }
357
358 delete $self->{content}->{SKIPPEDDIRS};
359 return $skipped;
360 }
361
362 sub hasexport()
363 {
364 my $self=shift;
365 # Check to see if there is a valid export block:
366 my $nkeys = $self->exporteddatatypes();
367 $nkeys > 0 ? return 1 : return 0;
368 }
369
370 sub has()
371 {
372 my $self=shift;
373 my ($datatype)=@_;
374 (exists ($self->{content}->{$datatype})) ? return 1 : return 0;
375 }
376
377 sub exported()
378 {
379 my $self=shift;
380 # Return a hash. Keys are type of data provided:
381 return ($self->{content}->{EXPORT});
382 }
383
384 sub exporteddatatypes()
385 {
386 my $self=shift;
387 # Return exported data types:
388 return keys %{$self->{content}->{EXPORT}};
389 }
390
391 sub buildproducts()
392 {
393 my $self=shift;
394 # Returns hash of build products and their data:
395 return $self->{content}->{BUILDPRODUCTS};
396 }
397
398 sub values()
399 {
400 my $self=shift;
401 my ($type)=@_;
402 # Get a list of values from known types
403 return $self->{content}->{BUILDPRODUCTS}->{$type};
404 }
405
406 sub basic_tags()
407 {
408 my $self=shift;
409 my $datatags=[];
410 my $buildtags=[ qw(BIN LIBRARY BUILDPRODUCTS) ];
411 my $skiptags=[ qw(ARCH EXPORT USE CLASSPATH) ];
412 my $otherskiptags=[ qw( SKIPPEDDIRS ) ];
413 my @all_skip_tags;
414
415 push(@all_skip_tags,@$skiptags,@$buildtags,@$otherskiptags);
416
417 foreach my $t (keys %{$self->{content}})
418 {
419 push(@$datatags,$t),if (! grep($t eq $_, @all_skip_tags));
420 }
421 return @{$datatags};
422 }
423
424 sub clean()
425 {
426 my $self=shift;
427 my (@tags) = @_;
428
429 # Delete some useless entries:
430 delete $self->{simpledoc};
431 delete $self->{id};
432 delete $self->{tagcontent};
433 delete $self->{nested};
434
435 delete $self->{DEPENDENCIES};
436
437 map
438 {
439 delete $self->{content}->{$_} if (exists($self->{content}->{$_}));
440 } @tags;
441
442 return $self;
443 }
444
445 sub AUTOLOAD()
446 {
447 my ($xmlparser,$name,%attributes)=@_;
448 return if $AUTOLOAD =~ /::DESTROY$/;
449 my $name=$AUTOLOAD;
450 $name =~ s/.*://;
451 }
452
453 1;