ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/XMLToolParser.pm
Revision: 1.3
Committed: Tue Nov 15 18:47:23 2005 UTC (19 years, 5 months ago) by sashby
Content type: text/plain
Branch: MAIN
CVS Tags: V1_0_3-p4, V1_0_3-p3, V1_0_3-p2, before110xmlBRmerge, V1_0_3-p1, V1_0_3
Branch point for: v103_with_xml
Changes since 1.2: +5 -7 lines
Log Message:
update to XMLToolParser

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