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

# Content
1 #
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 $self->{mydocversion}="1.1";
32 $self->init();
33 return $self;
34 }
35
36 sub init {
37 my $self=shift;
38 $self->{switch}=ActiveDoc::SimpleDoc->new();
39 $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 $self->{switch}->grouptag("Tool","setupinit");
52
53 $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 $self->{switch}->addtag("setup","Makefile",
71 \&Makefile_Start, $self,
72 \&Makefile_text, $self,
73 \&Makefile_end, $self);
74 $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
99 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 my $toolbox=shift;
116
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 if (($doctype ne $self->{mydoctype}) ||
129 (($self->{mydocversion} ne $docversion) && ($docversion ne "1.0")) ) {
130 $self->error("Unable to Parse Document of type $doctype $docversion".
131 "\n(Only ".$self->{mydoctype}." ". $self->{mydocversion}.")");
132 }
133 delete $self->{envcount};
134 $self->verbose("Pre-Parse");
135 $self->{switch}->parse("setupinit");
136 $self->{toolmakefile}=$toolbox->toolmakefile($name,$version);
137 $self->verbose("Setup Parse");
138 $self->{switch}->parse("setup");
139 undef $self->{toolmakefilefh};
140 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
175 my $OK='false';
176 my $file;
177
178 chomp $default;
179 $default=$self->_expandvars($default);
180 $self->verbose("Testing location");
181 print "Trying $default .... ";
182 if ( -f $default ) {
183 $OK="true";
184 $self->verbose("File OK");
185 }
186 else {
187 my $dh=DirHandle->new();
188 opendir $dh, $default or do { print "No $!\n"; return 0; };
189 ($#{$testfiles}==-1) ? $OK='false' : $OK='true';
190 print "\n";
191 my @files=readdir $dh;
192 undef $dh;
193 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 print "Existence Check Complete\n";
206 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 sub _askusermenu {
238 my $self=shift;
239 my $querystring=shift;
240 my @items=@_;
241
242 my $path=-1;
243 my $n;
244 while ( ($path!~/^\d+$/) || ($path > ($#items+1)) || ($path < 1) ) {
245 for (my $i=0; $i<=$#items; $i++ ) {
246 $n=$i+1;
247 print $n.") ".$items[$i]."\n";
248 }
249 print "\n".$querystring;
250 $path=<STDIN>;
251 chomp $path;
252 }
253 $path--;
254 return $path;
255 }
256
257 sub _askuser {
258 my $self=shift;
259 my $querystring=shift;
260 my $varname=shift;
261
262 my $type=$self->{tool}->type($varname);
263 my $path;
264 my $oldpath;
265 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 $oldpath=$path;
271 if ( $path ne "" ) {
272 ($path)=$self->_validateparam($type,$path);
273 if ( ! defined $path ) {
274 print "Error : ".$oldpath." is not valid.\n";
275 next;
276 }
277 }
278 return $path;
279 } #end for
280
281 }
282
283 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 #
309 # Propgate through the searcher collecting matching tools
310 #
311 sub _searchtools {
312 my $self=shift;
313 my $tool=shift;
314 my $searcher=shift;
315
316 my @tools=();
317 my $area;
318 my $rtool;
319 my $it=$searcher->newiterator();
320
321 while ( ! $it->last() ) {
322 $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 if ( defined $rtool ) {
328 if ( $rtool->equals($tool) ) {
329 $self->verbose("Found matching tool");
330 push @tools,$rtool;
331 }
332 else {
333 $self->verbose("Rejected tool ".$rtool->name()." "
334 .$rtool->version());
335 }
336 }
337 else {
338 $self->verbose("Tool Passed as Undefined");
339 }
340 }
341 else {
342 $self->verbose("Area passed is not defined");
343 }
344 }
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 my @validtools=();
359 if ( defined $self->{toolboxsearcher} ) {
360 @validtools=$self->_searchtools($tool,$self->{toolboxsearcher});
361 }
362 if ( $#validtools >=0 ) {
363 if ( ! $self->interactive() ) {
364 @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 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 # -- 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 }
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 }
487
488 # -- 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 sub Environment_Start {
507 my $self=shift;
508 my $name=shift;
509 my $hashref=shift;
510
511 $self->{switch}->checktag($name, $hashref, 'name');
512 if ( $self->{Arch} ) {
513 my $val=undef;
514 if ( defined $self->{EnvContext} ) {
515 $self->parserror(" Attempted to open new <$name> context".
516 " without closing the previous one");
517 }
518 # -- 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 $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 # 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 if ( exists $$hashref{'value'}) {
538 $val=$$hashref{'value'};
539 if ( $self->interactive() ) {
540 unshift @menulist,$$hashref{'value'};
541 }
542 }
543 # -- 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 }
551 # -- 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 }
557 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 }
574 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 }
597 $self->{Envvalue}=$val; # single val parameter
598 }
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 }