ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/ToolDoc.pm
Revision: 1.5
Committed: Wed Nov 15 10:50:57 2000 UTC (24 years, 5 months ago) by williamc
Content type: text/plain
Branch: MAIN
CVS Tags: V0_19_0, V0_18_5, V0_18_4, V_18_3_TEST, VO_18_3, V0_18_2, V0_18_1
Changes since 1.4: +48 -4 lines
Log Message:
import from V0_18_0

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