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

# User Rev Content
1 sashby 1.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 sashby 1.3 # Revision: $Id: XMLToolParser.pm,v 1.2 2005/11/11 19:23:59 sashby Exp $
8 sashby 1.1 #
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 sashby 1.3 my ($tool,$toolver,$file)=@_;
145    
146     $self->{tool}=$tool;
147     $self->{version}=$toolver;
148 sashby 1.1 $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;