ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/ToolParser.pm
(Generate patch)

Comparing COMP/SCRAM/src/BuildSystem/ToolParser.pm (file contents):
Revision 1.1 by sashby, Fri Feb 27 15:34:55 2004 UTC vs.
Revision 1.2 by sashby, Fri Dec 10 13:41:37 2004 UTC

# Line 0 | Line 1
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$
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;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines