ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/XMLToolParser.pm
Revision: 1.1
Committed: Tue Jul 26 15:14:00 2005 UTC (19 years, 9 months ago) by sashby
Content type: text/plain
Branch: MAIN
CVS Tags: V1_0_4p1, V1_0_2, V1_0_2_p1
Branch point for: v103_branch
Log Message:
Added XML version of ToolParser classes. Started to add support for upgrade mode of project command

File Contents

# Content
1 #____________________________________________________________________
2 # File: XMLToolParser.pm
3 #____________________________________________________________________
4 #
5 # Author: Shaun Ashby <Shaun.Ashby@cern.ch>
6 # Update: 2005-04-22 15:22:06+0200
7 # Revision: $Id: XMLToolParser.pm,v 1.2 2005/04/29 16:18:56 sashby Exp $
8 #
9 # Copyright: 2005 (C) Shaun Ashby
10 #
11 #--------------------------------------------------------------------
12 package BuildSystem::XMLToolParser;
13 require 5.004;
14 use Exporter;
15 use BuildSystem::XMLToolTagUtils;
16 use ActiveDoc::SimpleXMLDoc;
17 use Utilities::Verbose;
18
19 @ISA=qw(Exporter Utilities::Verbose);
20 @EXPORT_OK=qw( );
21
22 #
23 sub new()
24 ###############################################################
25 # new #
26 ###############################################################
27 # modified : Wed Dec 3 19:03:22 2003 / SFA #
28 # params : #
29 # : #
30 # function : #
31 # : #
32 ###############################################################
33 {
34 my $proto=shift;
35 my $class=ref($proto) || $proto;
36 my $self={};
37
38 bless $self,$class;
39
40 $self->{cache}=shift;
41 $self->{mydoctype}="BuildSystem::XMLToolParser";
42 $self->{mydocversion}="1.1";
43 $self->{interactive} = 0;
44 $self->{content} = {};
45 $self->{nested} = 0;
46 return $self;
47 }
48
49 sub _parser()
50 {
51 my $self=shift;
52
53 # Initialise the doc and a XML::Parser instance, passing in
54 # the default handlers for start, end and char types:
55 $self->{simplexmldoc} = ActiveDoc::SimpleXMLDoc->new(\&BuildSystem::XMLToolTagUtils::OpenTagHandler,
56 \&BuildSystem::XMLToolTagUtils::ClosingTagHandler,
57 \&BuildSystem::XMLToolTagUtils::CharHandler,
58 "setup");
59
60 # Pass a ref to parent object so that tag data can be stored
61 # directly in the XMLToolParser object:
62 &BuildSystem::XMLToolTagUtils::datastore($self);
63
64 # Register the specific tag routines with expected attributes. If no checking should be done
65 # then just put 0. For nested tags, last element is 1:
66 $self->{simplexmldoc}->registerTag("setup",
67 "use",
68 \&BuildSystem::XMLToolTagUtils::usetaghandler,
69 [ "name" ],
70 0);
71
72 $self->{simplexmldoc}->registerTag("setup",
73 "lib",
74 \&BuildSystem::XMLToolTagUtils::libtaghandler,
75 [ "name" ],
76 0);
77
78 $self->{simplexmldoc}->registerTag("setup",
79 "info",
80 \&BuildSystem::XMLToolTagUtils::infotaghandler,
81 [ "url" ],
82 0);
83
84 $self->{simplexmldoc}->registerTag("setup",
85 "flags",
86 \&BuildSystem::XMLToolTagUtils::flagstaghandler,
87 0,
88 0);
89
90 $self->{simplexmldoc}->registerTag("setup",
91 "environment",
92 \&BuildSystem::XMLToolTagUtils::environmenttaghandler,
93 [ "name" ],
94 0);
95
96 $self->{simplexmldoc}->registerTag("setup",
97 "runtime",
98 \&BuildSystem::XMLToolTagUtils::runtimetaghandler,
99 [ "name" ],
100 0);
101
102 $self->{simplexmldoc}->registerTag("setup",
103 "makefile",
104 \&BuildSystem::XMLToolTagUtils::makefiletaghandler,
105 0,
106 1);
107
108 # Nested tags (i.e. tags that can contain other tags):
109 $self->{simplexmldoc}->registerTag("setup",
110 "client",
111 \&BuildSystem::XMLToolTagUtils::clienttaghandler,
112 0,
113 1);
114
115 $self->{simplexmldoc}->registerTag("setup",
116 "architecture",
117 \&BuildSystem::XMLToolTagUtils::archtaghandler,
118 [ "name" ],
119 1);
120 # The main tool handler:
121 $self->{simplexmldoc}->registerTag("setup",
122 "tool",
123 \&BuildSystem::XMLToolTagUtils::tooltaghandler,
124 [ "name", "version" ],
125 1);
126
127 # Register the XML parsing tag routines (default ones, plus those added above):
128 $self->{simplexmldoc}->setHandlers();
129
130 # Return the parser object:
131 return $self->{simplexmldoc};
132 }
133
134 sub simplexmldoc()
135 {
136 my $self=shift;
137 @_ ? $self->{simplexmldoc} = shift
138 : $self->{simplexmldoc};
139 }
140
141 sub parse()
142 {
143 my $self=shift;
144 my ($tool,$toolver,$file)=@_;
145 $self->{tool}=$tool;
146 $self->{version}=$toolver;
147 $self->verbose("Setup Parse");
148 # Parse the file:
149 $self->_parser()->parsefile($file);
150 # We're done with the simpleXMLDoc object:
151 delete $self->{simplexmldoc};
152 }
153
154 sub pushlevel
155 {
156 my $self = shift;
157 my ($info, $nextlevel)=@_;
158
159 $self->{id} = $info if (defined $info);
160
161 # Check to see if last tag was arch: if so, ceate new level:
162 if ($self->{isarch} == 1)
163 {
164 $self->{nested} = 2;
165 $self->{nexttagcontent}={};
166 }
167 else
168 {
169 $self->{nested} = 1;
170 $self->{tagcontent}={};
171 }
172
173 # Set something which says "last starter tag was ARCH":
174 if ($nextlevel)
175 {
176 $self->{isarch} = 1;
177 }
178 }
179
180 sub poplevel
181 {
182 my $self = shift;
183
184 # Drop level of nesting by one:
185 $self->{nested}--;
186
187 if ($self->{isarch} != 1)
188 {
189 delete $self->{tagcontent};
190 }
191 }
192
193 sub rmenvdata
194 {
195 my $self=shift;
196 delete $self->{ENVDATA};
197 }
198
199 ###################################
200 ## Data Access Methods ##
201 ###################################
202 sub toolname
203 {
204 my $self=shift;
205 # Return tool name:
206 return ($self->{content}->{TOOLNAME});
207 }
208
209 sub toolversion
210 {
211 my $self=shift;
212 # Return tool version:
213 return ($self->{content}->{TOOLVERSION});
214 }
215
216 sub toolcontent
217 {
218 my $self=shift;
219 # Return whole of content hash:
220 return $self->{content};
221 }
222
223 sub getrawdata()
224 {
225 my $self=shift;
226 my ($tagtype)=@_;
227
228 # Check to see if we have data for this tag:
229 if (! exists ($self->{content}->{$tagtype}))
230 {
231 # If not, return:
232 return 0;
233 }
234
235 # Check the number of keys for hash referred to by this object.
236 # If 0, return:
237 if (ref($self->{content}->{$tagtype}) eq 'HASH') #
238 {
239 if ((my $nkeys=keys %{$self->{content}->{$tagtype}}) > 0)
240 {
241 # Return the data for the tag $tagtype. ARCH is a bit special because
242 # we want the data for the actual arch (thus, data is on a different level):
243 if ($tagtype eq 'ARCH')
244 {
245 my $archmatch = {};
246 # Check for matching arch key and return hash of relevant data.
247 # Also must take into account the fact that several arch names may match, e.g. Linux, Linux__2 and
248 # Linux__2.4 all match. If we find more than one match, collect ALL matching data and return it:
249 while (my ($k,$v) = each %{$self->{content}->{ARCH}})
250 {
251 # For every matching architecture we snatch the data and squirrel it away:
252 if ( $ENV{SCRAM_ARCH} =~ /$k.*/ )
253 {
254 # Now we check the tags inside the arch block. Note that we do not want to descend
255 # into CLIENT tags, if these exist. We just want to return all data in the ARCH
256 # block while making sure that multiple matches are handled correctly. We assume that
257 # you will only find one CLIENT block inside and ARCH:
258 while (my ($matchtag, $matchval) = each %{$v})
259 {
260 if ($matchtag =~ /CLIENT|FLAGS|RUNTIME/)
261 {
262 $archmatch->{$matchtag} = $matchval;
263 }
264 else
265 {
266 # Treat tags differently according to whether they are HASHes or ARRAYs:
267 if (ref($matchval) =~ /HASH/)
268 {
269 while (my ($t, $val) = each %{$matchval})
270 {
271 if (exists ($archmatch->{$matchtag}->{$t}))
272 {
273 push(@{$archmatch->{$matchtag}->{$t}},@$val);
274 }
275 else
276 {
277 $archmatch->{$matchtag}->{$t} = $val;
278 }
279 }
280 }
281 else # Here we deal with arrays:
282 {
283 if (exists ($archmatch->{$matchtag}))
284 {
285 push(@{$archmatch->{$matchtag}},@$matchval);
286 }
287 else
288 {
289 $archmatch->{$matchtag} = $matchval;
290 }
291 }
292 }
293 }
294 }
295 }
296 # Return the squirrel:
297 return $archmatch;
298
299 } # End of ARCH tag treatment
300 else
301 {
302 # Return other tag data:
303 return $self->{content}->{$tagtype};
304 }
305 }
306 else
307 {
308 print "Warning: $tagtype tags contain no other tag data!","\n";
309 return undef;
310 }
311 }
312 else
313 {
314 # We have an array of data or a scalar:
315 return $self->{content}->{$tagtype};
316 }
317 }
318
319 sub processrawtool()
320 {
321 my $self=shift;
322 my ($interactive) = @_;
323 my $data = [];
324 my $environments = {}; # Somewhere to collect our environments
325
326 # Set interactive mode if required:
327 $self->{interactive} = $interactive;
328
329 # Somewhere to store the data:
330 use BuildSystem::ToolData;
331 my $tooldataobj = BuildSystem::ToolData->new();
332
333 # Set the name and version:
334 $tooldataobj->toolname($self->toolname());
335 $tooldataobj->toolversion($self->toolversion());
336
337 # First, collect all tag data so that we only have non-nested tags.
338 # Check for architecture-dependent data first, followed by client tags:
339 foreach $nested_tag (qw( ARCH CLIENT ))
340 {
341 if (my $thisdata=$self->getrawdata($nested_tag))
342 {
343 foreach my $item (keys %{ $thisdata })
344 {
345 if ($item eq 'CLIENT')
346 {
347 my $clientdata = $thisdata->{$item};
348 foreach my $ckey (keys %{$clientdata})
349 {
350 $environments->{$ckey} = $clientdata->{$ckey};
351 }
352 }
353 elsif ($item eq 'ENVIRONMENT' || $item eq 'RUNTIME')
354 {
355 # Check to see if tag already exists before saving:
356 if (exists($environments->{$item}))
357 {
358 foreach my $ek (keys %{$thisdata})
359 {
360 if (exists($environments->{$item}->{$ek}))
361 {
362 push(@{$environments->{$item}->{$ek}}, @{$thisdata->{$item}->{$ek}});
363 }
364 else
365 {
366 $environments->{$item}->{$ek} = $thisdata->{$item}->{$ek};
367 }
368 }
369 }
370 else
371 {
372 # There isn't an entry yet:
373 $environments->{$item} = $thisdata->{$item};
374 }
375 }
376 else
377 {
378 my $data = $thisdata->{$item};
379
380 if (ref($data) eq 'HASH')
381 {
382 while (my ($f,$v) = each %$data)
383 {
384 $tooldataobj->flags($f,$v);
385 }
386 }
387 else
388 {
389 my $subname = lc($item);
390 $tooldataobj->$subname($data), if ($#$data != -1);
391 }
392 }
393 }
394 }
395 else
396 {
397 # No entry for this nested tag. Proceed.
398 next;
399 }
400 }
401
402 # Now handle all other normal tags:
403 foreach my $normal_tag (qw( ENVIRONMENT RUNTIME ))
404 {
405 # Do we have some data for this tag?
406 if (my $thisdata=$self->getrawdata($normal_tag))
407 {
408 # Add the data to our environments hash. We must check to see if
409 # there is an entry already:
410 if (exists($environments->{$normal_tag}))
411 {
412 foreach my $ek (keys %{$thisdata})
413 {
414 if (exists($environments->{$normal_tag}->{$ek}))
415 {
416 push(@{$environments->{$normal_tag}->{$ek}}, @{$thisdata->{$normal_tag}->{$ek}});
417 }
418 else
419 {
420 $environments->{$normal_tag}->{$ek} = $thisdata->{$normal_tag}->{$ek};
421 }
422 }
423 }
424 else
425 {
426 # There isn't an entry yet:
427 $environments->{$normal_tag} = $thisdata;
428 }
429 }
430 else
431 {
432 # No data so proceed:
433 next;
434 }
435 }
436
437 # Finally, tags that can be stored straight away:
438 foreach my $tag (qw( FLAGS MAKEFILE ))
439 {
440 my $bdata = $self->getrawdata($tag);
441 if (ref($bdata) eq 'HASH')
442 {
443 while (my ($f,$v) = each %$bdata)
444 {
445 $tooldataobj->flags($f,$v);
446 }
447 }
448 else
449 {
450 $tooldataobj->makefile($bdata), if ($#$bdata != -1);
451 }
452 }
453
454 # Libs and tool dependencise:
455 foreach my $tag (qw( LIB USE ))
456 {
457 my $bdata = $self->getrawdata($tag);
458 my $subname = lc($tag);
459 $tooldataobj->$subname($bdata), if ($#$bdata != -1);
460 }
461
462 # Also check to see if this tool is a scram-managed project. If
463 # so, set the SCRAM_PROJECT variable in the ToolData object:
464 if (exists ($self->{content}->{SCRAM_PROJECT}))
465 {
466 $tooldataobj->scram_project($self->{content}->{SCRAM_PROJECT});
467 }
468
469 # And check to see if this tool is a compiler. If so, set
470 # the SCRAM_COMPILER variable in the ToolData object:
471 if (exists ($self->{content}->{SCRAM_COMPILER}))
472 {
473 $tooldataobj->scram_compiler($self->{content}->{SCRAM_COMPILER});
474 }
475
476 # Establish the order of parsing the value strings:
477 my $order = $self->process_environments($environments);
478
479 if ($self->{interactive})
480 {
481 # Set the values interactively:
482 $self->interactively_find_settings($tooldataobj, $environments, $order);
483 }
484 else
485 {
486 # Set the values:
487 $self->find_settings($tooldataobj, $environments, $order);
488 }
489
490 # Return a ToolData object:
491 return $tooldataobj;
492 }
493
494 sub process_environments()
495 {
496 my $self=shift;
497 my ($environments)=@_;
498
499 use BuildSystem::SCRAMGrapher;
500 my $G = BuildSystem::SCRAMGrapher->new();
501
502 foreach $envtype (keys %{$environments})
503 {
504 while (my ($envcontent,$envdata) = each %{$environments->{$envtype}})
505 {
506 # Add a vertex for the VARIABLE name:
507 $G->vertex($envcontent);
508
509 foreach my $element (@$envdata)
510 {
511 if (exists($element->{'ELEMENTS'}))
512 {
513 map
514 {
515 # Add a path for each element in ELEMENTS:
516 $G->edge($envcontent, $_);
517 } @{$element->{'ELEMENTS'}};
518 }
519 }
520 }
521 }
522
523 my $setup_order = $G->sort();
524 return $setup_order;
525 }
526
527 sub find_settings()
528 {
529 my $self=shift;
530 my ($tooldataobj, $environments, $ordering)=@_;
531 my $stringtoeval;
532 my $runtime=[];
533 my $path;
534
535 use BuildSystem::ToolSettingValidator;
536
537 my $tsv = BuildSystem::ToolSettingValidator->new($environments, $self->toolname());
538
539 foreach my $envname (@$ordering)
540 {
541 my $type = 'ENVIRONMENT';
542 my $envdata = $tsv->environment($type, $envname);
543
544 # Handle single-occurrence variables first (i.e. VAR appears once
545 # in array of hashes):
546 if ($envdata != 0 && $#$envdata == 0) # One element only!
547 {
548 print "\nFinding a value for $envname:","\n";
549 print "\n";
550 # We have an environment and only one data element:
551 # Check the lookup DB:
552 if ($tsv->checkDB($envname))
553 {
554 print "\tValidating value for $envname (found in tool DB):","\n";
555 if ($tsv->validatepath())
556 {
557 # Save in TSV and store in ToolData object:
558 $tsv->savevalue($envname,$tsv->pathfromdb());
559 $self->store($tooldataobj, $envname, $tsv->pathfromdb());
560 }
561 else
562 {
563 $path = $tsv->findvalue($envname, $envdata);
564 # Save the value in ToolData object:
565 $self->store($tooldataobj, $envname, $path);
566 }
567 }
568 else
569 {
570 $path = $tsv->findvalue($envname, $envdata);
571 # Save in ToolData object:
572 $self->store($tooldataobj, $envname, $path);
573 }
574 }
575 elsif ($envdata != 0 && $#$envdata > 0)
576 {
577 print "\nFinding a value for $envname:","\n";
578 print "\n";
579 foreach my $elementdata (@$envdata)
580 {
581 $path = $tsv->findvalue($envname, $elementdata);
582 # Save in ToolData object:
583 $self->store($tooldataobj, $envname, $path);
584 }
585 }
586 elsif (exists($ENV{$envname}))
587 {
588 # Nothing to do here:
589 next;
590 }
591 else
592 {
593 push(@$runtime, $envname);
594 }
595 }
596
597 # Check that the required libraries exist:
598 $self->_lib_validate($tooldataobj);
599
600 # Now process the runtime settings:
601 print "\n";
602 print "-------------------------------\n";
603
604 foreach my $rtname (@$runtime)
605 {
606 my $type = 'RUNTIME';
607 my $envdata = $tsv->environment($type, $rtname);
608 my ($rttype,$realrtname) = split(':',$rtname);
609
610 # Only validate paths:
611 if ($rtname =~ /:/)
612 {
613 # Handle single-occurrence variables first (i.e. VAR appears once
614 # in array of hashes):
615 if ($envdata != 0 && $#$envdata == 0) # One element only!
616 {
617 print "\nRuntime path settings for $realrtname:","\n";
618 print "\n";
619 # We have an environment and only one data element:
620 # Check the lookup DB:
621 if ($tsv->checkDB($rtname))
622 {
623 print "\tValidating value for path $realrtname (found in tool DB):","\n";
624 if ($tsv->validatepath())
625 {
626 # Save in TSV and store in ToolData object:
627 $tsv->savevalue($rtname, $tsv->pathfromdb());
628 $tooldataobj->runtime($rtname, [ $tsv->pathfromdb() ]);
629 }
630 else
631 {
632 $path = $tsv->findvalue($rtname, $envdata);
633 # Save the value in ToolData object:
634 $tooldataobj->runtime($rtname, [ $path ]);
635 }
636 }
637 else
638 {
639 $path = $tsv->findvalue($rtname, $envdata);
640 # Save in ToolData object:
641 $tooldataobj->runtime($rtname, [ $path ]);
642 }
643 }
644 elsif ($envdata != 0 && $#$envdata > 0)
645 {
646 print "\nRuntime path settings for $realrtname:","\n";
647 print "\n";
648 foreach my $elementdata (@$envdata)
649 {
650 $path = $tsv->findvalue($rtname, $elementdata);
651 # Save in ToolData object:
652 $tooldataobj->runtime($rtname, [ $path ]);
653 }
654 }
655 else
656 {
657 next;
658 }
659 }
660 else
661 {
662 # Handle runtime variables:
663 if ($envdata != 0 && $#$envdata == 0) # One element only!
664 {
665 my $value='';
666 $tsv->checkdefaults($envdata, \$value);
667 print "\n";
668
669 # Chck to see if the value contains a variable that should be evaluated:
670 if ($value =~ /$/)
671 {
672 # If so, find the value and substitute. This should work for all
673 # occurrences of variables because by this point (and because the ordering
674 # was established at the start) all other variables will have real values:
675 my $dvalue = $tsv->_expandvars($value);
676 $value = $dvalue;
677 }
678
679 print "Runtime variable ",$rtname," set to \"",$value,"\"\n";
680
681 # Store the variable setting:
682 $tooldataobj->runtime($rtname, [ $value ]);
683 }
684 else
685 {
686 next;
687 }
688 }
689 }
690
691 print "\n";
692 }
693
694 sub interactively_find_settings()
695 {
696 my $self=shift;
697 my ($tooldataobj, $environments, $ordering)=@_;
698 my $stringtoeval;
699 my $runtime=[];
700 my ($path, $dpath);
701
702 use BuildSystem::ToolSettingValidator;
703
704 my $tsv = BuildSystem::ToolSettingValidator->new($environments, $self->toolname(), $self->{interactive});
705
706 foreach my $envname (@$ordering)
707 {
708 my $type = 'ENVIRONMENT';
709 my $envdata = $tsv->environment($type, $envname);
710
711 # Handle single-occurrence variables first (i.e. VAR appears once
712 # in array of hashes):
713 if ($envdata != 0 && $#$envdata == 0) # One element only!
714 {
715 print "\nFinding a value for $envname:","\n";
716 print "\n";
717 # We have an environment and only one data element:
718 # Check the lookup DB:
719 if ($tsv->checkDB($envname))
720 {
721 print "\tValidating value for $envname (found in tool DB):","\n";
722 if ($tsv->validatepath())
723 {
724 # This is our default:
725 $dpath = $tsv->pathfromdb();
726 # Run promptuser() to see if this value can be kept
727 # or should be changed:
728 $path = $tsv->promptuser($envname, $dpath);
729 # Save in TSV and store in ToolData object:
730 $tsv->savevalue($envname,$path);
731 $self->store($tooldataobj, $envname, $path);
732 }
733 else
734 {
735 $path = $tsv->ifindvalue($envname, $envdata);
736 # Save the value in ToolData object:
737 $self->store($tooldataobj, $envname, $path);
738 }
739 }
740 else
741 {
742 $dpath = $tsv->ifindvalue($envname, $envdata);
743 # Save in ToolData object:
744 $self->store($tooldataobj, $envname, $dpath);
745 }
746 }
747 elsif ($envdata != 0 && $#$envdata > 0)
748 {
749 print "\nFinding a value for $envname:","\n";
750 print "\n";
751 foreach my $elementdata (@$envdata)
752 {
753 $path = $tsv->ifindvalue($envname, $elementdata);
754 # Save in ToolData object:
755 $self->store($tooldataobj, $envname, $path);
756 }
757 }
758 elsif (exists($ENV{$envname}))
759 {
760 # Nothing to do here:
761 next;
762 }
763 else
764 {
765 push(@$runtime, $envname);
766 }
767 }
768
769 # Check that the required libraries exist:
770 $self->_lib_validate($tooldataobj);
771
772 # Now process the runtime settings:
773 print "\n";
774 print "-------------------------------\n";
775 foreach my $rtname (@$runtime)
776 {
777 my $type = 'RUNTIME';
778 my $envdata = $tsv->environment($type, $rtname);
779 my ($rttype,$realrtname) = split(':',$rtname);
780
781 # Only validate paths:
782 if ($rtname =~ /:/)
783 {
784 # Handle single-occurrence variables first (i.e. VAR appears once
785 # in array of hashes):
786 if ($envdata != 0 && $#$envdata == 0) # One element only!
787 {
788 print "\nRuntime path settings for $realrtname:","\n";
789 print "\n";
790 # We have an environment and only one data element:
791 # Check the lookup DB:
792 if ($tsv->checkDB($rtname))
793 {
794 print "\tValidating value for path $realrtname (found in tool DB):","\n";
795 if ($tsv->validatepath())
796 {
797 $dpath = $tsv->pathfromdb();
798 # Run promptuser() to see if this value can be kept
799 # or should be changed:
800 $path = $tsv->promptuser($rtname, $dpath);
801 # Save in TSV and store in ToolData object:
802 $tsv->savevalue($rtname, $path);
803 $tooldataobj->runtime($rtname, [ $path ]);
804 }
805 else
806 {
807 $dpath = $tsv->ifindvalue($rtname, $envdata);
808 # Save the value in ToolData object:
809 $tooldataobj->runtime($rtname, [ $path ]);
810 }
811 }
812 else
813 {
814 $path = $tsv->ifindvalue($rtname, $envdata);
815 # Save in ToolData object:
816 $tooldataobj->runtime($rtname, [ $path ]);
817 }
818 }
819 elsif ($envdata != 0 && $#$envdata > 0)
820 {
821 print "\nRuntime path settings for $realrtname:","\n";
822 print "\n";
823 foreach my $elementdata (@$envdata)
824 {
825 $path = $tsv->ifindvalue($rtname, $elementdata);
826 # Save in ToolData object:
827 $tooldataobj->runtime($rtname, [ $path ]);
828 }
829 }
830 else
831 {
832 next;
833 }
834 }
835 else
836 {
837 # Handle runtime variables:
838 if ($envdata != 0 && $#$envdata == 0) # One element only!
839 {
840 my $dvalue='';
841 $tsv->checkdefaults($envdata, \$dvalue);
842 print "\n";
843 my $value = $tsv->promptuserforvar($rtname, $dvalue);
844 # Store the variable setting:
845 $tooldataobj->runtime($rtname, [ $value ]);
846 }
847 else
848 {
849 next;
850 }
851 }
852 }
853
854 print "\n";
855 }
856
857 sub store()
858 {
859 my $self=shift;
860 my ($tooldataobj, $envname, $path) = @_;
861 my $subrtn = lc($envname);
862
863 if ($tooldataobj->can($subrtn))
864 {
865 $tooldataobj->$subrtn([ $path ]);
866 }
867 else
868 {
869 $tooldataobj->variable_data($envname, $path);
870 }
871 }
872
873 sub _lib_validate()
874 {
875 my $self=shift;
876 my ($toolobj)=@_;
877 my $errorstatus = { 0 => $main::good."[OK]".$main::normal, 1 => $main::error."[ERROR]".$main::normal };
878 my $libsfound={};
879
880 # Firstly, we check to see if there are libraries provided by this tool:
881 my @libraries = $toolobj->lib();
882 my @libpaths = $toolobj->libdir();
883
884 foreach my $ldir (@libpaths)
885 {
886 my $full_libname_glob="lib".$lib."*.*";
887 # Change to lib dir so we avoid the very long paths in our glob:
888 chdir($ldir);
889 # Next we use a glob to get libs matching this string (so we
890 # can see if there's a shared or archive lib):
891 my @possible_libs = glob($full_libname_glob);
892 #
893 map
894 {
895 $_ =~ s/\.so*|\.a*//g; # Remove all endings
896 # Store in our hash of found libs:
897 $libsfound->{$_} = 1;
898 } @possible_libs;
899 }
900
901 # Next we iterate over the list of libraries in our tool and
902 # see if it was found in one of the libdirs:
903 print "\n\n", if ($#libraries != -1);
904 foreach my $library (@libraries)
905 {
906 # Good status:
907 my $errorid = 0;
908 if (! exists ($libsfound->{'lib'.$library}))
909 {
910 # Check in system library dirs:
911 if ($self->_check_system_libs($library))
912 {
913 $errorid = 0;
914 }
915 else
916 {
917 $errorid = 1;
918 }
919 }
920 printf("* Library check %-10s for lib%-12s\n",$errorstatus->{$errorid}, $library);
921 }
922
923 print "\n";
924 }
925
926 sub _check_system_libs()
927 {
928 my $self=shift;
929 my ($lib)=@_;
930 my $libsfound = {};
931 my $systemdirs = [ qw( /lib /usr/lib /usr/local/lib /usr/X11R6/lib ) ];
932 my $full_libname_glob="lib".$lib."*.*";
933 my $found = 0;
934
935 foreach my $dir (@$systemdirs)
936 {
937 # Change to lib dir so we avoid the very long paths in our glob:
938 chdir($dir);
939 # Next we use a glob to get libs matching this string (so we
940 # can see if there's a shared or archive lib):
941 my @possible_libs = glob($full_libname_glob);
942 #
943 map
944 {
945 $_ =~ s/\.so*|\.a*//g; # Remove all endings
946 # Store in our hash of found libs:
947 $libsfound->{$_} = 1;
948 } @possible_libs;
949 }
950
951 # See if we find the library in the system lib directories:
952 if (! exists ($libsfound->{'lib'.$library}))
953 {
954 $found = 1;
955 }
956
957 return $found;
958 }
959
960 1;