ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/ToolParser.pm
Revision: 1.4
Committed: Wed Apr 13 16:45:36 2005 UTC (20 years ago) by sashby
Content type: text/plain
Branch: MAIN
CVS Tags: v102p1
Changes since 1.3: +8 -1 lines
Log Message:
Start to add support for user interaction with compiler meta.

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.4 # Revision: $Id: ToolParser.pm,v 1.3 2005/03/03 18:57:58 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 sashby 1.4
442     # And check to see if this tool is a compiler. If so, set
443     # the SCRAM_COMPILER variable in the ToolData object:
444     if (exists ($self->{content}->{SCRAM_COMPILER}))
445     {
446     $tooldataobj->scram_compiler($self->{content}->{SCRAM_COMPILER});
447     }
448 sashby 1.2
449     # Establish the order of parsing the value strings:
450     my $order = $self->process_environments($environments);
451    
452     if ($self->{interactive})
453     {
454     # Set the values interactively:
455     $self->interactively_find_settings($tooldataobj, $environments, $order);
456     }
457     else
458     {
459     # Set the values:
460     $self->find_settings($tooldataobj, $environments, $order);
461     }
462    
463     # Return a ToolData object:
464     return $tooldataobj;
465     }
466    
467     sub process_environments()
468     {
469     my $self=shift;
470     my ($environments)=@_;
471    
472     use BuildSystem::SCRAMGrapher;
473     my $G = BuildSystem::SCRAMGrapher->new();
474    
475     foreach $envtype (keys %{$environments})
476     {
477     while (my ($envcontent,$envdata) = each %{$environments->{$envtype}})
478     {
479     # Add a vertex for the VARIABLE name:
480     $G->vertex($envcontent);
481    
482     foreach my $element (@$envdata)
483     {
484     if (exists($element->{'ELEMENTS'}))
485     {
486     map
487     {
488     # Add a path for each element in ELEMENTS:
489     $G->edge($envcontent, $_);
490     } @{$element->{'ELEMENTS'}};
491     }
492     }
493     }
494     }
495    
496     my $setup_order = $G->sort();
497     return $setup_order;
498     }
499    
500     sub find_settings()
501     {
502     my $self=shift;
503     my ($tooldataobj, $environments, $ordering)=@_;
504     my $stringtoeval;
505     my $runtime=[];
506     my $path;
507    
508     use BuildSystem::ToolSettingValidator;
509    
510     my $tsv = BuildSystem::ToolSettingValidator->new($environments, $self->toolname());
511    
512     foreach my $envname (@$ordering)
513     {
514     my $type = 'ENVIRONMENT';
515     my $envdata = $tsv->environment($type, $envname);
516    
517     # Handle single-occurrence variables first (i.e. VAR appears once
518     # in array of hashes):
519     if ($envdata != 0 && $#$envdata == 0) # One element only!
520     {
521     print "\nFinding a value for $envname:","\n";
522     print "\n";
523     # We have an environment and only one data element:
524     # Check the lookup DB:
525     if ($tsv->checkDB($envname))
526     {
527     print "\tValidating value for $envname (found in tool DB):","\n";
528     if ($tsv->validatepath())
529     {
530     # Save in TSV and store in ToolData object:
531     $tsv->savevalue($envname,$tsv->pathfromdb());
532     $self->store($tooldataobj, $envname, $tsv->pathfromdb());
533     }
534     else
535     {
536     $path = $tsv->findvalue($envname, $envdata);
537     # Save the value in ToolData object:
538     $self->store($tooldataobj, $envname, $path);
539     }
540     }
541     else
542     {
543     $path = $tsv->findvalue($envname, $envdata);
544     # Save in ToolData object:
545     $self->store($tooldataobj, $envname, $path);
546     }
547     }
548     elsif ($envdata != 0 && $#$envdata > 0)
549     {
550     print "\nFinding a value for $envname:","\n";
551     print "\n";
552     foreach my $elementdata (@$envdata)
553     {
554     $path = $tsv->findvalue($envname, $elementdata);
555     # Save in ToolData object:
556     $self->store($tooldataobj, $envname, $path);
557     }
558     }
559     elsif (exists($ENV{$envname}))
560     {
561     # Nothing to do here:
562     next;
563     }
564     else
565     {
566     push(@$runtime, $envname);
567     }
568     }
569    
570     # Check that the required libraries exist:
571     $self->_lib_validate($tooldataobj);
572    
573     # Now process the runtime settings:
574     print "\n";
575     print "-------------------------------\n";
576    
577     foreach my $rtname (@$runtime)
578     {
579     my $type = 'RUNTIME';
580     my $envdata = $tsv->environment($type, $rtname);
581     my ($rttype,$realrtname) = split(':',$rtname);
582 sashby 1.3
583 sashby 1.2 # Only validate paths:
584     if ($rtname =~ /:/)
585     {
586     # Handle single-occurrence variables first (i.e. VAR appears once
587     # in array of hashes):
588     if ($envdata != 0 && $#$envdata == 0) # One element only!
589     {
590     print "\nRuntime path settings for $realrtname:","\n";
591     print "\n";
592     # We have an environment and only one data element:
593     # Check the lookup DB:
594     if ($tsv->checkDB($rtname))
595     {
596     print "\tValidating value for path $realrtname (found in tool DB):","\n";
597     if ($tsv->validatepath())
598     {
599     # Save in TSV and store in ToolData object:
600     $tsv->savevalue($rtname, $tsv->pathfromdb());
601     $tooldataobj->runtime($rtname, [ $tsv->pathfromdb() ]);
602     }
603     else
604     {
605     $path = $tsv->findvalue($rtname, $envdata);
606     # Save the value in ToolData object:
607     $tooldataobj->runtime($rtname, [ $path ]);
608     }
609     }
610     else
611     {
612     $path = $tsv->findvalue($rtname, $envdata);
613     # Save in ToolData object:
614     $tooldataobj->runtime($rtname, [ $path ]);
615     }
616     }
617     elsif ($envdata != 0 && $#$envdata > 0)
618     {
619     print "\nRuntime path settings for $realrtname:","\n";
620     print "\n";
621     foreach my $elementdata (@$envdata)
622     {
623     $path = $tsv->findvalue($rtname, $elementdata);
624     # Save in ToolData object:
625     $tooldataobj->runtime($rtname, [ $path ]);
626     }
627     }
628     else
629     {
630     next;
631     }
632     }
633     else
634     {
635     # Handle runtime variables:
636     if ($envdata != 0 && $#$envdata == 0) # One element only!
637     {
638     my $value='';
639     $tsv->checkdefaults($envdata, \$value);
640     print "\n";
641    
642     # Chck to see if the value contains a variable that should be evaluated:
643     if ($value =~ /$/)
644     {
645     # If so, find the value and substitute. This should work for all
646     # occurrences of variables because by this point (and because the ordering
647     # was established at the start) all other variables will have real values:
648     my $dvalue = $tsv->_expandvars($value);
649     $value = $dvalue;
650     }
651    
652     print "Runtime variable ",$rtname," set to \"",$value,"\"\n";
653    
654     # Store the variable setting:
655     $tooldataobj->runtime($rtname, [ $value ]);
656     }
657     else
658     {
659     next;
660     }
661     }
662     }
663    
664     print "\n";
665     }
666    
667     sub interactively_find_settings()
668     {
669     my $self=shift;
670     my ($tooldataobj, $environments, $ordering)=@_;
671     my $stringtoeval;
672     my $runtime=[];
673     my ($path, $dpath);
674    
675     use BuildSystem::ToolSettingValidator;
676    
677     my $tsv = BuildSystem::ToolSettingValidator->new($environments, $self->toolname(), $self->{interactive});
678    
679     foreach my $envname (@$ordering)
680     {
681     my $type = 'ENVIRONMENT';
682     my $envdata = $tsv->environment($type, $envname);
683    
684     # Handle single-occurrence variables first (i.e. VAR appears once
685     # in array of hashes):
686     if ($envdata != 0 && $#$envdata == 0) # One element only!
687     {
688     print "\nFinding a value for $envname:","\n";
689     print "\n";
690     # We have an environment and only one data element:
691     # Check the lookup DB:
692     if ($tsv->checkDB($envname))
693     {
694     print "\tValidating value for $envname (found in tool DB):","\n";
695     if ($tsv->validatepath())
696     {
697     # This is our default:
698     $dpath = $tsv->pathfromdb();
699     # Run promptuser() to see if this value can be kept
700     # or should be changed:
701     $path = $tsv->promptuser($envname, $dpath);
702     # Save in TSV and store in ToolData object:
703     $tsv->savevalue($envname,$path);
704     $self->store($tooldataobj, $envname, $path);
705     }
706     else
707     {
708     $path = $tsv->ifindvalue($envname, $envdata);
709     # Save the value in ToolData object:
710     $self->store($tooldataobj, $envname, $path);
711     }
712     }
713     else
714     {
715     $dpath = $tsv->ifindvalue($envname, $envdata);
716     # Save in ToolData object:
717     $self->store($tooldataobj, $envname, $dpath);
718     }
719     }
720     elsif ($envdata != 0 && $#$envdata > 0)
721     {
722     print "\nFinding a value for $envname:","\n";
723     print "\n";
724     foreach my $elementdata (@$envdata)
725     {
726     $path = $tsv->ifindvalue($envname, $elementdata);
727     # Save in ToolData object:
728     $self->store($tooldataobj, $envname, $path);
729     }
730     }
731     elsif (exists($ENV{$envname}))
732     {
733     # Nothing to do here:
734     next;
735     }
736     else
737     {
738     push(@$runtime, $envname);
739     }
740     }
741    
742     # Check that the required libraries exist:
743     $self->_lib_validate($tooldataobj);
744    
745     # Now process the runtime settings:
746     print "\n";
747     print "-------------------------------\n";
748     foreach my $rtname (@$runtime)
749     {
750     my $type = 'RUNTIME';
751     my $envdata = $tsv->environment($type, $rtname);
752     my ($rttype,$realrtname) = split(':',$rtname);
753    
754     # Only validate paths:
755     if ($rtname =~ /:/)
756     {
757     # Handle single-occurrence variables first (i.e. VAR appears once
758     # in array of hashes):
759     if ($envdata != 0 && $#$envdata == 0) # One element only!
760     {
761     print "\nRuntime path settings for $realrtname:","\n";
762     print "\n";
763     # We have an environment and only one data element:
764     # Check the lookup DB:
765     if ($tsv->checkDB($rtname))
766     {
767     print "\tValidating value for path $realrtname (found in tool DB):","\n";
768     if ($tsv->validatepath())
769     {
770     $dpath = $tsv->pathfromdb();
771     # Run promptuser() to see if this value can be kept
772     # or should be changed:
773     $path = $tsv->promptuser($rtname, $dpath);
774     # Save in TSV and store in ToolData object:
775     $tsv->savevalue($rtname, $path);
776     $tooldataobj->runtime($rtname, [ $path ]);
777     }
778     else
779     {
780     $dpath = $tsv->ifindvalue($rtname, $envdata);
781     # Save the value in ToolData object:
782     $tooldataobj->runtime($rtname, [ $path ]);
783     }
784     }
785     else
786     {
787     $path = $tsv->ifindvalue($rtname, $envdata);
788     # Save in ToolData object:
789     $tooldataobj->runtime($rtname, [ $path ]);
790     }
791     }
792     elsif ($envdata != 0 && $#$envdata > 0)
793     {
794     print "\nRuntime path settings for $realrtname:","\n";
795     print "\n";
796     foreach my $elementdata (@$envdata)
797     {
798     $path = $tsv->ifindvalue($rtname, $elementdata);
799     # Save in ToolData object:
800     $tooldataobj->runtime($rtname, [ $path ]);
801     }
802     }
803     else
804     {
805     next;
806     }
807     }
808     else
809     {
810     # Handle runtime variables:
811     if ($envdata != 0 && $#$envdata == 0) # One element only!
812     {
813     my $dvalue='';
814     $tsv->checkdefaults($envdata, \$dvalue);
815     print "\n";
816     my $value = $tsv->promptuserforvar($rtname, $dvalue);
817     # Store the variable setting:
818     $tooldataobj->runtime($rtname, [ $value ]);
819     }
820     else
821     {
822     next;
823     }
824     }
825     }
826    
827     print "\n";
828     }
829    
830     sub store()
831     {
832     my $self=shift;
833     my ($tooldataobj, $envname, $path) = @_;
834     my $subrtn = lc($envname);
835    
836     if ($tooldataobj->can($subrtn))
837     {
838     $tooldataobj->$subrtn([ $path ]);
839     }
840     else
841     {
842     $tooldataobj->variable_data($envname, $path);
843     }
844     }
845    
846     sub _lib_validate()
847     {
848     my $self=shift;
849     my ($toolobj)=@_;
850     my $errorstatus = { 0 => $main::good."[OK]".$main::normal, 1 => $main::error."[ERROR]".$main::normal };
851     my $libsfound={};
852    
853     # Firstly, we check to see if there are libraries provided by this tool:
854     my @libraries = $toolobj->lib();
855     my @libpaths = $toolobj->libdir();
856    
857     foreach my $ldir (@libpaths)
858     {
859     my $full_libname_glob="lib".$lib."*.*";
860     # Change to lib dir so we avoid the very long paths in our glob:
861     chdir($ldir);
862     # Next we use a glob to get libs matching this string (so we
863     # can see if there's a shared or archive lib):
864     my @possible_libs = glob($full_libname_glob);
865     #
866     map
867     {
868     $_ =~ s/\.so*|\.a*//g; # Remove all endings
869     # Store in our hash of found libs:
870     $libsfound->{$_} = 1;
871     } @possible_libs;
872     }
873    
874     # Next we iterate over the list of libraries in our tool and
875     # see if it was found in one of the libdirs:
876     print "\n\n", if ($#libraries != -1);
877     foreach my $library (@libraries)
878     {
879     # Good status:
880     my $errorid = 0;
881     if (! exists ($libsfound->{'lib'.$library}))
882     {
883     # Check in system library dirs:
884     if ($self->_check_system_libs($library))
885     {
886     $errorid = 0;
887     }
888     else
889     {
890     $errorid = 1;
891     }
892     }
893     printf("* Library check %-10s for lib%-12s\n",$errorstatus->{$errorid}, $library);
894     }
895    
896     print "\n";
897     }
898    
899     sub _check_system_libs()
900     {
901     my $self=shift;
902     my ($lib)=@_;
903     my $libsfound = {};
904     my $systemdirs = [ qw( /lib /usr/lib /usr/local/lib /usr/X11R6/lib ) ];
905     my $full_libname_glob="lib".$lib."*.*";
906     my $found = 0;
907    
908     foreach my $dir (@$systemdirs)
909     {
910     # Change to lib dir so we avoid the very long paths in our glob:
911     chdir($dir);
912     # Next we use a glob to get libs matching this string (so we
913     # can see if there's a shared or archive lib):
914     my @possible_libs = glob($full_libname_glob);
915     #
916     map
917     {
918     $_ =~ s/\.so*|\.a*//g; # Remove all endings
919     # Store in our hash of found libs:
920     $libsfound->{$_} = 1;
921     } @possible_libs;
922     }
923    
924     # See if we find the library in the system lib directories:
925     if (! exists ($libsfound->{'lib'.$library}))
926     {
927     $found = 1;
928     }
929    
930     return $found;
931     }
932    
933     1;