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

# 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.2.1 # Revision: $Id: XMLToolParser.pm,v 1.3 2005/11/15 18:47:23 sashby Exp $
8 sashby 1.1 #
9     # Copyright: 2005 (C) Shaun Ashby
10     #
11     #--------------------------------------------------------------------
12     package BuildSystem::XMLToolParser;
13 sashby 1.3.2.1
14     BEGIN
15     {
16     die "\n\n".__PACKAGE__.": this package can be dropped from releases.\n\n";
17     }
18    
19 sashby 1.1 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 sashby 1.3 my ($tool,$toolver,$file)=@_;
151    
152     $self->{tool}=$tool;
153     $self->{version}=$toolver;
154 sashby 1.1 $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;