ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/XMLReqUtils.pm
Revision: 1.5
Committed: Fri Jan 14 17:36:42 2011 UTC (14 years, 3 months ago) by muzaffar
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 1.4: +1 -1 lines
State: FILE REMOVED
Log Message:
merged SCRAM_V2 branch in to head

File Contents

# Content
1 #____________________________________________________________________
2 # File: XMLReqUtils.pm
3 #____________________________________________________________________
4 #
5 # Author: Shaun ASHBY <Shaun.Ashby@cern.ch>
6 # Update: 2005-07-26 14:58:38+0200
7 # Revision: $Id: XMLReqUtils.pm,v 1.4 2007/12/14 09:03:49 muzaffar Exp $
8 #
9 # Copyright: 2005 (C) Shaun ASHBY
10 #
11 #--------------------------------------------------------------------
12 package BuildSystem::XMLReqUtils;
13
14 BEGIN
15 {
16 die "\n\n".__PACKAGE__.": this package can be dropped from releases.\n\n";
17 }
18
19 require 5.004;
20
21 use Exporter;
22
23 @ISA=qw(Exporter);
24 @EXPORT_OK=qw( );
25
26 # This package provides all subroutines for supported tags found
27 # in requirements docs:
28 sub new
29 {
30 my $proto=shift;
31 my $class=ref($proto) || $proto;
32 my $self={};
33
34 bless $self,$class;
35 return $self;
36 }
37
38 #### Core XML Register Functions ####
39 sub OpenTagHandler()
40 {
41 my $xmlparser=shift;
42 my ($element, %attributes)=@_;
43
44 # Elementary doc checks:
45 if ($element eq 'doc')
46 {
47 if ($attributes{'type'} ne 'Requirements')
48 {
49 die "SCRAM Error: Unable to parse this document! Wrong type!","\n";
50 }
51 return;
52 }
53
54 # Store the name of the current tag environment:
55 $self->{currentenv} = $element;
56 $self->simplexmldoc()->checkattributes($element, \%attributes);
57 &{$self->simplexmldoc()->gettagfunction($element)}($element, \%attributes);
58 }
59
60 sub ClosingTagHandler()
61 {
62 my $xmlparser=shift;
63 my ($element)=@_;
64
65 if ($element eq 'doc')
66 {
67 return;
68 }
69
70 if (grep($element eq $_, @{$self->simplexmldoc()->nested()}))
71 {
72 &{$self->simplexmldoc()->gettagfunction($element)}($element, {}, 1);
73 }
74
75 # Reset the current env (i.e. delete entry):
76 delete $self->{currentenv};
77 }
78
79 sub CharHandler()
80 {
81 my ($xmlparser, @items) = @_;
82 return if ($items[0] =~ /\s*/);
83
84 # Check to see if there's a content entry in $self
85 # for the current tag. If so, append the line to it:
86 if (grep($self->{currentenv} eq $_, @{$self->simplexmldoc()->nested()}))
87 {
88 &{$self->simplexmldoc()->gettagfunction($self->{currentenv})}($self->{currentenv},
89 {}, 2, [ @items ]);
90 }
91 }
92
93 ## Tag routines ##
94 sub requirementstaghandler()
95 {
96 my ($name, $hashref, $nesting) = @_;
97 # Do nothing for char handler:
98 return if ($nesting == 2);
99
100 if ($nesting == 1)
101 {
102 # Cleanup whatever needs to be cleaned up:
103
104 }
105 else
106 {
107
108 }
109
110 # Return here only if the current element is "requirements":
111 return;
112 }
113
114 sub usetaghandler()
115 {
116 my ($name, $hashref) = @_;
117 push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{USE}},$$hashref{'name'});
118 }
119
120 sub libtaghandler()
121 {
122 my ($name, $hashref) = @_;
123 push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{LIB}},$$hashref{'name'});
124 }
125
126 sub infotaghandler()
127 {
128 my ($name, $hashref) = @_;
129 $self->{"$self->{levels}->[$self->{nested}]".content}->{INFO} = $hashref;
130 }
131
132 sub flagstaghandler()
133 {
134 my ($name, $hashref, $nesting) = @_;
135 # Do nothing for char handler:
136 return if ($nesting == 2);
137 # Do nothing for closing tag handler:
138 return if ($nesting == 1);
139
140 # Extract the flag name and its value:
141 my ($flagname,$flagvaluestring) = each %{$hashref};
142 $flagname =~ tr/[a-z]/[A-Z]/; # Keep flag name uppercase
143 chomp($flagvaluestring);
144 # Split the value on whitespace so we can push all
145 # individual flags into an array:
146 my @flagvalues = split(' ',$flagvaluestring);
147
148 # Is current tag within another tag block?
149 if ($self->{nested} > 0)
150 {
151 # Check to see if the current flag name is already stored in the hash. If so,
152 # just add the new values to the array of flag values:
153 if (exists ($self->{"$self->{levels}->[$self->{nested}]".content}->{FLAGS}->{$flagname}))
154 {
155 push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{FLAGS}->{$flagname}},@flagvalues);
156 }
157 else
158 {
159 $self->{"$self->{levels}->[$self->{nested}]".content}->{FLAGS}->{$flagname} = [ @flagvalues ];
160 }
161 }
162 else
163 {
164 if (exists ($self->{content}->{FLAGS}->{$flagname}))
165 {
166 push(@{$self->{content}->{FLAGS}->{$flagname}},@flagvalues);
167 }
168 else
169 {
170 $self->{content}->{FLAGS}->{$flagname} = [ @flagvalues ];
171 }
172 }
173 }
174
175 sub environmenttaghandler()
176 {
177 my ($name, $hashref, $nesting) = @_;
178 # Do nothing for char handler:
179 return if ($nesting == 2);
180 # Do nothing for closing tag handler:
181 return if ($nesting == 1);
182
183 # Save a copy of the name of this environment:
184 my $envname=$$hashref{'name'};
185 delete $$hashref{'name'}; # Delete name entry so hash is more tidy
186 # Break the value/default value into its constituent parts:
187 foreach my $t (qw(value default))
188 {
189 if (exists ($$hashref{$t}))
190 {
191 $hashref->{ELEMENTS} = [];
192 map
193 {
194 if ($_ =~ m|\$(.*)?|)
195 {
196 push(@{$hashref->{ELEMENTS}},$1);
197 }
198 } split("/",$hashref->{$t});
199 }
200 }
201
202 # Before we save $hashref we need to know if there are already
203 # any env tags with the same name. If there are, we must save all
204 # data to an aray of hashes:
205 if (exists ($self->{"$self->{levels}->[$self->{nested}]".content}->{ENVIRONMENT}->{$envname}))
206 {
207 push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{ENVIRONMENT}->{$envname}},$hashref);
208 }
209 else
210 {
211 # No entry yet so just store the hashref:
212 $self->{"$self->{levels}->[$self->{nested}]".content}->{ENVIRONMENT}->{$envname} = [ $hashref ];
213 }
214 }
215
216 sub runtimetaghandler()
217 {
218 my ($name, $hashref, $nesting) = @_;
219 # Do nothing for char handler:
220 return if ($nesting == 2);
221 # Do nothing for closing tag handler:
222 return if ($nesting == 1);
223
224 my $envname;
225
226 # Break the value/default value into its constituent parts:
227 foreach my $t (qw(value default))
228 {
229 if (exists ($$hashref{$t}))
230 {
231 $hashref->{ELEMENTS} = [];
232 map
233 {
234 # In some cases, we might set a runtime path (e.g. LD_LIBRARY_PATH) to
235 # a proper path value i.e. X:Y. In this case, don't bother adding the string
236 # as a "variable" to ELEMENTS:
237 if ($_ =~ m|\$(.*)?| && $_ !~ /:/)
238 {
239 push(@{$hashref->{ELEMENTS}},$1);
240 }
241 } split("/",$hashref->{$t});
242 }
243 }
244
245 # Check to see if we have a "type" arg. If so, we use this to create the key:
246 if (exists ($hashref->{'type'}))
247 {
248 my $type=$hashref->{'type'};
249 # Make the type uppercase:
250 $type =~ tr/[a-z]/[A-Z]/;
251 # Rename the environment as "<type>:<env name>":
252 $envname = $type.":".$$hashref{'name'};
253 }
254 else
255 {
256 $envname = $$hashref{'name'};
257 }
258
259 # Delete name entry so hash is more tidy
260 delete $$hashref{'name'};
261
262 # Before we save $hashref we need to know if there are already
263 # any runtime tags with the same name. If there are, we must save all
264 # data to an aray of hashes:
265 if (exists ($self->{"$self->{levels}->[$self->{nested}]".content}->{RUNTIME}->{$envname}))
266 {
267 push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{RUNTIME}->{$envname}},$hashref);
268 }
269 else
270 {
271 # No entry yet so just store the hashref:
272 $self->{"$self->{levels}->[$self->{nested}]".content}->{RUNTIME}->{$envname} = [ $hashref ];
273 }
274 }
275
276 sub makefiletaghandler()
277 {
278 my ($name, $hashref, $nesting, $string)=@_;
279
280 if ($nesting == 1)
281 {
282 push(@{$self->{"$self->{levels}->[$self->{nested}]".content}->{MAKEFILE}},
283 join('',@{$self->{makefilecontent}}));
284 delete $self->{makefilecontent};
285 }
286 elsif ($nesting == 2)
287 {
288 # Store the text content:
289 push(@{$self->{makefilecontent}}, @$string);
290 }
291 else
292 {
293 # Start the tag:
294 $self->{makefilecontent} = [];
295 }
296 }
297
298 sub clienttaghandler()
299 {
300 my ($name, $hashref, $nesting) = @_;
301 # Do nothing for char handler:
302 return if ($nesting == 2);
303
304 if ($nesting == 1)
305 {
306 if ($self->{isarch} == 1)
307 {
308 # If we already have an architecture tag, we must write to tagcontent hash:
309 $self->{tagcontent}->{CLIENT}=$self->{nexttagcontent};
310 delete $self->{nexttagcontent};
311 }
312 else
313 {
314 $self->{content}->{CLIENT}=$self->{tagcontent};
315 }
316
317 $self->poplevel();
318 }
319 else
320 {
321 $self->pushlevel();
322 }
323 }
324
325 sub archtaghandler()
326 {
327 my ($name, $hashref, $nesting) = @_;
328 # Do nothing for char handler:
329 return if ($nesting == 2);
330
331 if ($nesting == 1)
332 {
333 # Need to be able to cope with multiple arch blocks with same arch string:
334 if (exists ($self->{content}->{ARCH}->{$self->{id}->{'name'}}))
335 {
336 # Already have an architecture tag for this arch:
337 while (my ($k,$v) = each %{$self->{tagcontent}})
338 {
339 # If this tag (e.g. LIB, USE, MAKEFILE) already exists and (as we know
340 # it should be) its data is an ARRAY, push it to the store:
341 if (exists ($self->{content}->{ARCH}->{$self->{id}->{'name'}}->{$k}) &&
342 ref($v) eq 'ARRAY')
343 {
344 push(@{$self->{content}->{ARCH}->{$self->{id}->{'name'}}->{$k}},@$v);
345 }
346 else
347 {
348 # Otherwise (for HASH data) we just store it. Note that, because we do
349 # not loop over the HASH content and check for already existsing keys,
350 # if two arch blocks with same arch name define the same tag (e.g, ENV),
351 # the last occurrence will be kept (i.e. the two values won't be added
352 # to one ENV hash): //FIXME for later....
353 $self->{content}->{ARCH}->{$self->{id}->{'name'}}->{$k} = $v;
354 }
355 }
356 }
357 else
358 {
359 $self->{content}->{ARCH}->{$self->{id}->{'name'}}=$self->{tagcontent};
360 }
361
362 delete $self->{isarch};
363 $self->poplevel();
364 }
365 else
366 {
367 $self->pushlevel($hashref, 1); # Set nested to 1;
368 }
369 }
370
371 # Data-handling utility functions:
372 sub datastore()
373 {
374 my $obj=shift;
375 $self = $obj;
376 }
377
378 1;