ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/ToolParser.pm
Revision: 1.3
Committed: Thu Mar 3 18:57:58 2005 UTC (20 years, 2 months ago) by sashby
Content type: text/plain
Branch: MAIN
CVS Tags: V1_0_1
Changes since 1.2: +2 -2 lines
Log Message:
Added warn feature so that missing dirs can prompt a warning rather than stopping for user-input.

File Contents

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