ViewVC Help
View File | Revision Log | Show Annotations | Root Listing
root/cvsroot/COMP/SCRAM/src/BuildSystem/ToolDoc.pm
Revision: 1.1.2.14.2.1.2.3.2.3.2.1
Committed: Wed Nov 8 16:11:14 2000 UTC (24 years, 6 months ago) by williamc
Content type: text/plain
CVS Tags: BuildSystemProto1, V0_18_0model
Changes since 1.1.2.14.2.1.2.3.2.3: +52 -7 lines
Log Message:
Import from V0_17_1

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