ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/ToolParser.pm
Revision: 1.2
Committed: Fri Dec 10 13:41:37 2004 UTC (20 years, 4 months ago) by sashby
Content type: text/plain
Branch: MAIN
CVS Tags: V1_0_0
Changes since 1.1: +926 -0 lines
Log Message:
Merged V1_0 branch to HEAD

File Contents

# Content
1 #____________________________________________________________________
2 # File: ToolParser.pm
3 #____________________________________________________________________
4 #
5 # Author: Shaun Ashby <Shaun.Ashby@cern.ch>
6 # Update: 2004-02-09 20:14:55+0100
7 # Revision: $Id: ToolParser.pm,v 1.1.2.17 2004/10/27 12:35:25 sashby Exp $
8 #
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
576 # 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;