ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/ToolDoc.pm
Revision: 1.6
Committed: Fri Oct 19 18:14:23 2001 UTC (23 years, 6 months ago) by sashby
Content type: text/plain
Branch: MAIN
Changes since 1.5: +3 -2 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 williamc 1.2 #
2     # ToolDoc.pm
3     #
4     # Originally Written by Christopher Williams
5     #
6     # Description
7     # -----------
8     # SimpleDoc interface to initialise Tool objects
9     #
10     # Interface
11     # ---------
12     # new() : A new ToolDoc object
13     # tool(toolobj) : set the tool object for the class
14     # toolsearcher(searcher) : set the searcher for finding reference tools
15     # setup(file,$name,$version) : setup a tool object from the specified file
16     # return 0 for OK 1 for cancel
17     # interactive([0|1]) : set the interactive node 0=off 1=on
18    
19     package BuildSystem::ToolDoc;
20     require 5.004;
21     use ActiveDoc::SimpleDoc;
22     use Utilities::Verbose;
23     @ISA=qw(Utilities::Verbose);
24    
25     sub new {
26     my $class=shift;
27     $self={};
28     bless $self, $class;
29     $self->{cache}=shift;
30     $self->{mydoctype}="BuildSystem::ToolDoc";
31 williamc 1.5 $self->{mydocversion}="1.1";
32 williamc 1.2 $self->init();
33     return $self;
34     }
35    
36     sub init {
37     my $self=shift;
38     $self->{switch}=ActiveDoc::SimpleDoc->new();
39 williamc 1.4 $self->{switch}->newparse("setupinit");
40     $self->{switch}->addtag("setupinit","Tool",\&Tool_Start, $self,
41     "", $self,
42     \&Tool_End, $self);
43     $self->{switch}->addtag("setupinit", "Architecture",
44     \&Arch_Start,$self,
45     "", $self,
46     \&Arch_End,$self);
47     $self->{switch}->addtag("setupinit","Environment",
48     \&Environment_init, $self,
49     "", $self,
50     "", $self);
51 williamc 1.5 $self->{switch}->grouptag("Tool","setupinit");
52    
53 williamc 1.2 $self->{switch}->newparse("setup");
54     $self->{switch}->addtag("setup","Tool",\&Tool_Start, $self,
55     "", $self,
56     \&Tool_End, $self);
57     $self->{switch}->addtag("setup","Lib",\&Lib, $self,
58     "", $self,
59     "", $self);
60     $self->{switch}->addtag("setup","External",\&External_Start, $self,
61     "", $self,
62     "", $self);
63     $self->{switch}->addtag("setup","Client",\&Client_start, $self,
64     "", $self,
65     \&Client_end, $self);
66     $self->{switch}->addtag("setup","Environment",
67     \&Environment_Start, $self,
68     \&Env_text, $self,
69     \&Environment_End, $self);
70 williamc 1.5 $self->{switch}->addtag("setup","Makefile",
71     \&Makefile_Start, $self,
72     \&Makefile_text, $self,
73     \&Makefile_end, $self);
74 williamc 1.2 $self->{switch}->grouptag("Tool","setup");
75     $self->{switch}->addtag("setup","Architecture",
76     \&Arch_Start,$self,
77     "", $self,
78     \&Arch_End,$self);
79     $self->{Arch}=1;
80     push @{$self->{ARCHBLOCK}}, $self->{Arch};
81    
82     }
83    
84     sub interactive {
85     my $self=shift;
86    
87     @_?$self->{interactive}=shift
88     :((defined $self->{interactive})?$self->{interactive}:0);
89     }
90    
91     sub tool {
92     my $self=shift;
93     $self->{tool}=shift;
94     }
95    
96     sub toolsearcher {
97     my $self=shift;
98 sashby 1.6
99 williamc 1.2 if ( @_ ) {
100     my $searcher=shift;
101     if ( ! defined $searcher ) {
102     $self->error("Undefined Value passed as a Searcher".
103     " in ToolDoc::toolsearcher");
104     }
105     $self->{toolboxsearcher}=$searcher;
106     }
107     return $self->{toolboxsearcher};
108     }
109    
110     sub setup {
111     my $self=shift;
112     my $file=shift;
113     my $name=shift;
114     my $version=shift;
115 williamc 1.5 my $toolbox=shift;
116 williamc 1.2
117     $self->{ToolEnv}{'SCRAMtoolname'}=$name;
118     $self->{ToolEnv}{'SCRAMtoolversion'}=$version;
119     $self->{ToolEnv}{'SCRAM_ARCH'}=$ENV{'SCRAM_ARCH'};
120    
121     $name=~tr[A-Z][a-z];
122     $self->{tool}->name($name);
123     $self->{tool}->version($version);
124     $self->{switch}->filetoparse($file);
125     $self->{toolfound}=1;
126     # -- check the type of document - can we parse it?
127     my($doctype,$docversion)=$self->{switch}->doctype();
128 williamc 1.5 if (($doctype ne $self->{mydoctype}) ||
129     (($self->{mydocversion} ne $docversion) && ($docversion ne "1.0")) ) {
130 williamc 1.2 $self->error("Unable to Parse Document of type $doctype $docversion".
131     "\n(Only ".$self->{mydoctype}." ". $self->{mydocversion}.")");
132     }
133 williamc 1.4 delete $self->{envcount};
134 williamc 1.5 $self->verbose("Pre-Parse");
135 williamc 1.4 $self->{switch}->parse("setupinit");
136 williamc 1.5 $self->{toolmakefile}=$toolbox->toolmakefile($name,$version);
137     $self->verbose("Setup Parse");
138 williamc 1.2 $self->{switch}->parse("setup");
139 williamc 1.5 undef $self->{toolmakefilefh};
140 williamc 1.2 return $self->{toolfound};
141     }
142    
143     sub featuretext {
144     my $self=shift;
145     my $feature=shift;
146    
147     if ( @_ ) {
148     $self->{featuretext}{$feature}=shift;
149     }
150     else {
151     return ($self->{featuretext}{$feature});
152     }
153     }
154    
155     sub _checkdefault {
156     my $self=shift;
157     my $hashref=shift;
158    
159     if ( defined $$hashref{'default'} ) { #check default
160     my $default;
161     foreach $default ( split /:/, $$hashref{'default'} ) {
162     $default=~s/\"//;
163     if ($self->_testlocation($default,
164     [ $self->{tool}->getfeature($$hashref{'type'})] )) { return 1; }
165     }
166     }
167     return 0;
168     }
169    
170     sub _testlocation {
171     my $self=shift;
172     my $default=shift;
173     my $testfiles=shift;
174 williamc 1.4
175 williamc 1.2 my $OK='false';
176     my $file;
177    
178     chomp $default;
179     $default=$self->_expandvars($default);
180 williamc 1.4 $self->verbose("Testing location");
181 williamc 1.2 print "Trying $default .... ";
182     if ( -f $default ) {
183     $OK="true";
184 williamc 1.4 $self->verbose("File OK");
185 williamc 1.2 }
186     else {
187 williamc 1.4 my $dh=DirHandle->new();
188     opendir $dh, $default or do { print "No $!\n"; return 0; };
189 williamc 1.2 ($#{$testfiles}==-1) ? $OK='false' : $OK='true';
190     print "\n";
191 williamc 1.4 my @files=readdir $dh;
192     undef $dh;
193 williamc 1.2 foreach $file ( @$testfiles ) {
194     print " Checking for $file .... ";
195     # now check that the required files are actually there
196     if ( ( $number = grep /\Q$file\L/, @files) == 0 ) {
197     $OK='false';
198     print "not found\n";
199     last;
200     }
201     print "found\n";
202     }
203     }
204     if ( $OK eq 'true' ) {
205 williamc 1.5 print "Existence Check Complete\n";
206 williamc 1.2 return 1
207     }
208     return 0
209     }
210    
211     sub _expandvars {
212     my $self=shift;
213     my $string=shift;
214    
215     return "" , if ( ! defined $string );
216     $string=~s{
217     \$\((\w+)\)
218     }{
219     if (defined $self->{ToolEnv}{$1}) {
220     $self->_expandvars($self->{ToolEnv}{$1});
221     } else {
222     "\$$1";
223     }
224     }egx;
225     $string=~s{
226     \$(\w+)
227     }{
228     if (defined $self->{ToolEnv}{$1}) {
229     $self->_expandvars($self->{ToolEnv}{$1});
230     } else {
231     "\$$1";
232     }
233     }egx;
234     return $string;
235     }
236    
237 williamc 1.3 sub _askusermenu {
238     my $self=shift;
239     my $querystring=shift;
240     my @items=@_;
241    
242     my $path=-1;
243 williamc 1.4 my $n;
244     while ( ($path!~/^\d+$/) || ($path > ($#items+1)) || ($path < 1) ) {
245 williamc 1.3 for (my $i=0; $i<=$#items; $i++ ) {
246 williamc 1.4 $n=$i+1;
247     print $n.") ".$items[$i]."\n";
248 williamc 1.3 }
249     print "\n".$querystring;
250     $path=<STDIN>;
251     chomp $path;
252     }
253 williamc 1.4 $path--;
254 williamc 1.3 return $path;
255     }
256 williamc 1.2
257     sub _askuser {
258     my $self=shift;
259     my $querystring=shift;
260     my $varname=shift;
261    
262 williamc 1.4 my $type=$self->{tool}->type($varname);
263     my $path;
264     my $oldpath;
265 williamc 1.2 print $self->featuretext($self->{EnvContext});
266     for ( ;; ) {
267     print "\n".$querystring." (RETURN to log as missing)\nset $varname = ";
268     $path=<STDIN>;
269     chomp $path;
270 williamc 1.4 $oldpath=$path;
271 williamc 1.2 if ( $path ne "" ) {
272 williamc 1.4 ($path)=$self->_validateparam($type,$path);
273     if ( ! defined $path ) {
274     print "Error : ".$oldpath." is not valid.\n";
275     next;
276     }
277 williamc 1.2 }
278 williamc 1.4 return $path;
279 williamc 1.2 } #end for
280    
281     }
282    
283 williamc 1.4 sub _validateparam {
284     my $self=shift;
285     my $type=shift;
286     my @params=@_;
287    
288     my @newparams=();
289     foreach $param ( @params ) {
290     if ( defined $self->{'client'}) { # must be a location
291     if ( $self->_testlocation($param ,
292     [ $self->{tool}->getfeature($type)] )) {
293     $self->verbose("$param passed validation");
294     push @newparams,$param;
295     }
296     else {
297     $self->verbose("$param failed validation");
298     }
299     }
300     else {
301     # --- no other tests to pass so it must be OK
302     push @newparams,$param;
303     }
304     }
305     return @newparams;
306     }
307    
308 williamc 1.2 #
309     # Propgate through the searcher collecting matching tools
310     #
311     sub _searchtools {
312     my $self=shift;
313     my $tool=shift;
314 williamc 1.4 my $searcher=shift;
315 williamc 1.2
316     my @tools=();
317     my $area;
318     my $rtool;
319 williamc 1.4 my $it=$searcher->newiterator();
320 sashby 1.6
321 williamc 1.4 while ( ! $it->last() ) {
322 williamc 1.2 $area=$it->next();
323     if ( defined $area ) {
324     $self->verbose("Searching for ".$tool->name()." ".
325     $tool->version()." in ".$area->location());
326     $rtool=$area->toolbox()->gettool($tool->name(),$tool->version());
327 williamc 1.3 if ( defined $rtool ) {
328     if ( $rtool->equals($tool) ) {
329     $self->verbose("Found matching tool");
330 williamc 1.2 push @tools,$rtool;
331 williamc 1.3 }
332     else {
333     $self->verbose("Rejected tool ".$rtool->name()." "
334     .$rtool->version());
335     }
336 williamc 1.2 }
337 williamc 1.4 else {
338     $self->verbose("Tool Passed as Undefined");
339     }
340 williamc 1.2 }
341 williamc 1.3 else {
342     $self->verbose("Area passed is not defined");
343     }
344 williamc 1.2 }
345     return @tools;
346     }
347    
348     # search toolboxes for a nice list
349     #
350     sub _toolparamcopy {
351     my $self=shift;
352     my $tool=shift;
353     my $param=shift;
354    
355     my $rv=0;
356     my @params=();
357     $self->verbose("Check Other Projects for tool");
358 williamc 1.4 my @validtools=();
359     if ( defined $self->{toolboxsearcher} ) {
360     @validtools=$self->_searchtools($tool,$self->{toolboxsearcher});
361     }
362     if ( $#validtools >=0 ) {
363     if ( ! $self->interactive() ) {
364 williamc 1.2 @params=$validtools[0]->getfeature($param);
365     if ( $#params >=0 ) {
366     $self->verbose("Extracting Feature $param from tool".
367     " (= @params )\n");
368     $rv=1;
369     }
370     }
371     }
372     return ($rv,@params);
373     }
374    
375 williamc 1.4 sub _getparamsets {
376     my $self=shift;
377     my $tool=shift;
378     my $param=shift;
379    
380     my @paramlist=();
381     my @params=();
382     $self->verbose("Searching for parameter settings in other tools");
383     my @validtools=();
384     if ( defined $self->{toolboxsearcher} ) {
385     @validtools=$self->_searchtools($tool,$self->{toolboxsearcher});
386     }
387     else {
388     $self->verbose("No tool searcher available");
389     }
390     if ( $#validtools >=0 ) {
391     foreach $t ( @validtools ) {
392     @params=$t->getfeature($param);
393     if ( $#params >=0 ) {
394     push @paramlist, [ @params ];
395     $self->verbose("Found @params");
396     }
397     }
398     }
399     return @paramlist;
400     }
401    
402 williamc 1.2 # -- Tag Routines
403    
404     sub Client_start {
405     my $self=shift;
406     my $name=shift;
407     my $hashref=shift;
408    
409     if ( $self->{Arch} ) {
410     $self->{'client'}=1;
411     }
412     }
413    
414     sub Client_end {
415     my $self=shift;
416     if ( $self->{Arch} ) {
417     undef $self->{'client'};
418     }
419     }
420    
421     sub Tool_Start {
422     my $self=shift;
423     my $name=shift;
424     my $hashref=shift;
425    
426     $self->{switch}->checktag($name, $hashref, 'name');
427     $self->{switch}->checktag($name, $hashref, 'version');
428     $self->{switch}->opengroup("Toolactive");
429    
430     # lower case the name
431     $$hashref{'name'}=~tr[A-Z][a-z];
432     # make sure we only pick up the tool requested
433     if ( ( $self->{tool}->name() eq $$hashref{'name'} ) &&
434     ($self->{tool}->version() eq $$hashref{'version'})) {
435     $self->{switch}->
436     allowgroup("Toolactive",$self->{switch}->currentparsename());
437     $self->{ToolEnv}{'SCRAMtoolname'}=$$hashref{'name'};
438     $self->{ToolEnv}{'SCRAMtoolversion'}=$$hashref{'version'};
439     $self->{toolfound}=0;
440     }
441     else {
442     $self->{switch}->disallowgroup("Toolactive",
443     $self->{switch}->currentparsename());
444     }
445     }
446    
447     sub Tool_End {
448     my $self=shift;
449     my $name=shift;
450     my $hashref=shift;
451    
452     $self->{switch}->closegroup("Toolactive");
453 williamc 1.5 }
454    
455     sub Makefile_Start {
456     my $self=shift;
457     my $name=shift;
458     my $hashref=shift;
459    
460     if ( $self->{Arch} ) {
461     if ( ! defined $self->{toolmakefilefh} ) {
462     $self->{toolmakefilefh}=FileHandle->new();
463     $self->{toolmakefilefh}->open(">".$self->{toolmakefile});
464     }
465     }
466     }
467    
468     sub Makefile_text {
469     my $self=shift;
470     my $name=shift;
471     my $string=shift;
472    
473     if ( $self->{Arch} ) {
474     print {$self->{toolmakefilefh}} $string;
475     }
476     }
477    
478     sub Makefile_end {
479     my $self=shift;
480     my $name=shift;
481     my $hashref=shift;
482    
483     if ( $self->{Arch} ) {
484     print {$self->{toolmakefilefh}} "\n";
485     }
486 williamc 1.2 }
487    
488 williamc 1.4 # -- collect number of variables of the same name - need to know how many
489     # before main setup processing
490     sub Environment_init {
491     my $self=shift;
492     my $name=shift;
493     my $hashref=shift;
494    
495     $self->{switch}->checktag($name, $hashref, 'name');
496     if ( $self->{Arch} ) {
497     if ( exists $self->{envcount}{$$hashref{'name'}} ) {
498     $self->{envcount}{$$hashref{'name'}}++;
499     }
500     else {
501     $self->{envcount}{$$hashref{'name'}}=0;
502     }
503     }
504     }
505    
506 williamc 1.2 sub Environment_Start {
507     my $self=shift;
508     my $name=shift;
509     my $hashref=shift;
510 sashby 1.6
511 williamc 1.2 $self->{switch}->checktag($name, $hashref, 'name');
512     if ( $self->{Arch} ) {
513 williamc 1.4 my $val=undef;
514 williamc 1.2 if ( defined $self->{EnvContext} ) {
515     $self->parserror(" Attempted to open new <$name> context".
516     " without closing the previous one");
517     }
518 williamc 1.4 # -- keep a counter of the number of times we see this variable
519     if ( exists $self->{EnvironmentCount}{$$hashref{'name'}} ) {
520     $self->{EnvironmentCount}{$$hashref{'name'}}++;
521     }
522     else {
523     $self->{EnvironmentCount}{$$hashref{'name'}}=0;
524     }
525    
526 williamc 1.2 $self->{currentenvtext}="";
527     $self->{EnvContext}=$$hashref{'name'};
528     undef $self->{Envvalue};
529     if ( exists $$hashref{'type'} ) {
530     $$hashref{'type'}=~tr[A-Z][a-z];
531     $self->{tool}->type($$hashref{'name'},$$hashref{'type'});
532     }
533 williamc 1.4 # check other installed copies of the tool
534     # -- construct a menu of options
535     my @menulist=();
536     # -- a value is fixed - unless interactive switch is on
537 williamc 1.2 if ( exists $$hashref{'value'}) {
538 williamc 1.4 $val=$$hashref{'value'};
539     if ( $self->interactive() ) {
540     unshift @menulist,$$hashref{'value'};
541     }
542 williamc 1.2 }
543 williamc 1.4 # -- add any default values to the selection
544     if ( ! defined $val ) {
545     if ( $self->_checkdefault($hashref) ) {
546     my $var=$self->_expandvars($$hashref{'default'});
547     if ( !grep { $_ eq $var } @menulist ) {
548     unshift @menulist, $var;
549     }
550 williamc 1.2 }
551 williamc 1.4 # -- check the environment
552     if ( defined $ENV{$$hashref{'name'}} ) {
553     if ( !grep { $_ eq $ENV{$$hashref{'name'}}} @menulist ) {
554     unshift @menulist, $ENV{$$hashref{'name'}};
555     }
556 williamc 1.2 }
557 williamc 1.4 my @paramlist=$self->_getparamsets($self->{tool},
558     $$hashref{'name'});
559     foreach $p ( @paramlist ) {
560     # -- only add them if there are the same number of variables
561     if ( $#{$p} == $self->{envcount}{$$hashref{'name'}} ) {
562     if ( !grep {$_ eq $$p[$self->{EnvironmentCount}
563     {$$hashref{'name'}}] } @menulist) {
564     push @menulist,$$p[$self->{EnvironmentCount}
565     {$$hashref{'name'}}];
566     }
567     }
568     else {
569     $self->verbose("Ignoring tool params - not the same number".
570     " defined (".$#{$p}." != ".
571     $self->{envcount}{$$hashref{'name'}}.")");
572     }
573 williamc 1.2 }
574 williamc 1.4 if ( $#menulist >=0 ) {
575     print "Validating Values for Variable : ".$$hashref{'name'}."\n";
576     @menulist=$self->_validateparam($$hashref{'type'},@menulist);
577     }
578     # -- If theres only one option take it without asking
579     if ( $#menulist == 0 && ( ! $self->interactive() )) {
580     $val=$menulist[0];
581     }
582     elsif ( $#menulist > 0 ) {
583     my $in=$self->_askusermenu(
584     "Multiple possibilities found for ".
585     $$hashref{'name'}." ( occurance ".
586     ($self->{EnvironmentCount}{$$hashref{'name'}}+1)." ) ".
587     "\nPlease Choose: ",
588     (@menulist,"Other"));
589     if ( $in <=$#menulist ) {
590     $val=$menulist[$in];
591     }
592     else {
593     undef $val;
594     }
595     }
596 williamc 1.2 }
597 williamc 1.4 $self->{Envvalue}=$val; # single val parameter
598 williamc 1.2 }
599     }
600    
601     sub Env_text {
602     my $self=shift;
603     my $name=shift;
604     my $string=shift;
605    
606     if ( $self->{Arch} ) {
607     $self->{currentenvtext}=$self->{currentenvtext}.$string;
608     }
609     }
610    
611     sub Environment_End {
612     my $self=shift;
613     my $name=shift;
614    
615     if ( $self->{Arch} ) {
616     if ( ! defined $self->{EnvContext} ) {
617     $self->{switch}->parseerror("</$name> without an opening context");
618     }
619     # - set the help text
620     $self->featuretext($self->{EnvContext},$self->{currentenvtext});
621     if ( ! defined $self->{Envvalue} ) {
622     $self->{Envvalue}=$self->_askuser("Please Enter the Value Below:",
623     $self->{EnvContext});
624     }
625     $self->{Envvalue}=$self->_expandvars($self->{Envvalue});
626     $self->{tool}->addfeature($self->{EnvContext}, $self->{Envvalue});
627     $self->{ToolEnv}{$self->{EnvContext}}=$self->{Envvalue};
628     undef $self->{EnvContext};
629     undef $self->{Envvalue};
630     }
631     }
632    
633     sub Lib {
634     my $self=shift;
635     my $name=shift;
636     my $hashref=shift;
637    
638     $self->{switch}->checktag($name, $hashref, 'name');
639     if ( $self->{Arch} ) {
640     $self->{tool}->addfeature("lib",$$hashref{'name'});
641     }
642     }
643    
644     sub External_Start {
645     my $self=shift;
646     my $name=shift;
647     my $hashref=shift;
648    
649     $self->{switch}->checktag($name, $hashref,'ref');
650     if ( $self->{Arch} ) {
651     $self->{tool}->addfeature("_externals",$$hashref{'ref'});
652     }
653     }
654    
655     sub Arch_Start {
656     my $self=shift;
657     my $name=shift;
658     my $hashref=shift;
659    
660     $self->{switch}->checktag($name, $hashref,'name');
661     ( ($ENV{SCRAM_ARCH}=~/$$hashref{name}.*/) )? ($self->{Arch}=1)
662     : ($self->{Arch}=0);
663     push @{$self->{ARCHBLOCK}}, $self->{Arch};
664     }
665    
666     sub Arch_End {
667     my $self=shift;
668     my $name=shift;
669    
670     pop @{$self->{ARCHBLOCK}};
671     $self->{Arch}=$self->{ARCHBLOCK}[$#{$self->{ARCHBLOCK}}];
672     }