ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/XMLToolParser.pm
Revision: 1.3.2.1
Committed: Wed Jan 24 13:24:38 2007 UTC (18 years, 3 months ago) by sashby
Content type: text/plain
Branch: v103_with_xml
CVS Tags: forV1_1_0, v103_xml_071106, V110p2, V110p1
Changes since 1.3: +7 -1 lines
Log Message:
Start to drop obsolete packages from recent XML prototyping.

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