ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/XMLToolParser.pm
Revision: 1.2
Committed: Fri Nov 11 19:23:59 2005 UTC (19 years, 5 months ago) by sashby
Content type: text/plain
Branch: MAIN
Changes since 1.1: +7 -4 lines
Log Message:
*** empty log message ***

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