ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/ToolDoc.pm
Revision: 1.7
Committed: Thu Nov 15 21:18:16 2001 UTC (23 years, 5 months ago) by sashby
Content type: text/plain
Branch: MAIN
Changes since 1.6: +64 -45 lines
Log Message:
Committing the days changes.

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