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.2
Committed: Mon Oct 30 17:39:12 2000 UTC (24 years, 6 months ago) by williamc
Content type: text/plain
Branch: V0_16branch
CVS Tags: V0_16_3
Changes since 1.1.2.14.2.1.2.3.2.1: +41 -15 lines
Log Message:
Better validation of variable candidates

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