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 |
+ |
my $OK='false'; |
149 |
+ |
my $file; |
150 |
+ |
|
151 |
+ |
chomp $default; |
152 |
+ |
$default=$self->_expandvars($default); |
153 |
+ |
print "Trying $default .... "; |
154 |
+ |
if ( -f $default ) { |
155 |
+ |
$OK="true"; |
156 |
+ |
} |
157 |
+ |
else { |
158 |
+ |
my $fh=FileHandle->new(); |
159 |
+ |
opendir $fh, $default or do { print "No \n"; return 0; }; |
160 |
+ |
($#{$testfiles}==-1) ? $OK='false' : $OK='true'; |
161 |
+ |
print "\n"; |
162 |
+ |
my @files=readdir $fh; |
163 |
+ |
undef $fh; |
164 |
+ |
foreach $file ( @$testfiles ) { |
165 |
+ |
print " Checking for $file .... "; |
166 |
+ |
# now check that the required files are actually there |
167 |
+ |
if ( ( $number = grep /\Q$file\L/, @files) == 0 ) { |
168 |
+ |
$OK='false'; |
169 |
+ |
print "not found\n"; |
170 |
+ |
last; |
171 |
+ |
} |
172 |
+ |
print "found\n"; |
173 |
+ |
} |
174 |
+ |
} |
175 |
+ |
if ( $OK eq 'true' ) { |
176 |
+ |
print "Directory Check Complete\n"; |
177 |
+ |
return 1 |
178 |
+ |
} |
179 |
+ |
return 0 |
180 |
+ |
} |
181 |
+ |
|
182 |
+ |
sub _expandvars { |
183 |
+ |
my $self=shift; |
184 |
+ |
my $string=shift; |
185 |
+ |
|
186 |
+ |
return "" , if ( ! defined $string ); |
187 |
+ |
$string=~s{ |
188 |
+ |
\$\((\w+)\) |
189 |
+ |
}{ |
190 |
+ |
if (defined $self->{ToolEnv}{$1}) { |
191 |
+ |
$self->_expandvars($self->{ToolEnv}{$1}); |
192 |
+ |
} else { |
193 |
+ |
"\$$1"; |
194 |
+ |
} |
195 |
+ |
}egx; |
196 |
+ |
$string=~s{ |
197 |
+ |
\$(\w+) |
198 |
+ |
}{ |
199 |
+ |
if (defined $self->{ToolEnv}{$1}) { |
200 |
+ |
$self->_expandvars($self->{ToolEnv}{$1}); |
201 |
+ |
} else { |
202 |
+ |
"\$$1"; |
203 |
+ |
} |
204 |
+ |
}egx; |
205 |
+ |
return $string; |
206 |
+ |
} |
207 |
+ |
|
208 |
+ |
|
209 |
+ |
sub _askuser { |
210 |
+ |
my $self=shift; |
211 |
+ |
my $querystring=shift; |
212 |
+ |
my $varname=shift; |
213 |
+ |
|
214 |
+ |
print $self->featuretext($self->{EnvContext}); |
215 |
+ |
for ( ;; ) { |
216 |
+ |
print "\n".$querystring." (RETURN to log as missing)\nset $varname = "; |
217 |
+ |
$path=<STDIN>; |
218 |
+ |
chomp $path; |
219 |
+ |
if ( $path ne "" ) { |
220 |
+ |
if ( defined $self->{'client'}) { # must be a location |
221 |
+ |
if ( $self->_testlocation($path , "H", $Envtype{$type} )) { |
222 |
+ |
return $path; |
223 |
+ |
} |
224 |
+ |
print "Error : ".$path." does not exist.\n"; |
225 |
+ |
next; |
226 |
+ |
} |
227 |
+ |
} |
228 |
+ |
else { |
229 |
+ |
return $path; |
230 |
+ |
} |
231 |
+ |
} #end for |
232 |
+ |
|
233 |
+ |
} |
234 |
+ |
|
235 |
+ |
# |
236 |
+ |
# Propgate through the searcher collecting matching tools |
237 |
+ |
# |
238 |
+ |
sub _searchtools { |
239 |
+ |
my $self=shift; |
240 |
+ |
my $tool=shift; |
241 |
+ |
|
242 |
+ |
my @tools=(); |
243 |
+ |
my $area; |
244 |
+ |
my $rtool; |
245 |
+ |
if ( defined $self->{toolboxsearcher} ) { |
246 |
+ |
my $it=$self->{toolboxsearcher}->newiterator(); |
247 |
+ |
while ( ! $it->last() ) { |
248 |
+ |
$area=$it->next(); |
249 |
+ |
if ( defined $area ) { |
250 |
+ |
$self->verbose("Searching for ".$tool->name()." ". |
251 |
+ |
$tool->version()." in ".$area->location()); |
252 |
+ |
$rtool=$area->toolbox()->gettool($tool->name(),$tool->version()); |
253 |
+ |
if ( (defined $rtool) && $rtool->equals($tool) ) { |
254 |
+ |
push @tools,$rtool; |
255 |
+ |
} |
256 |
+ |
} |
257 |
+ |
} |
258 |
+ |
} |
259 |
+ |
return @tools; |
260 |
+ |
} |
261 |
+ |
|
262 |
+ |
# search toolboxes for a nice list |
263 |
+ |
# |
264 |
+ |
sub _toolparamcopy { |
265 |
+ |
my $self=shift; |
266 |
+ |
my $tool=shift; |
267 |
+ |
my $param=shift; |
268 |
+ |
|
269 |
+ |
my $rv=0; |
270 |
+ |
my @params=(); |
271 |
+ |
$self->verbose("Check Other Projects for tool"); |
272 |
+ |
my @validtools=$self->_searchtools($tool); |
273 |
+ |
if ( ! $self->interactive() ) { |
274 |
+ |
if ( $#validtools >=0 ) { |
275 |
+ |
@params=$validtools[0]->getfeature($param); |
276 |
+ |
if ( $#params >=0 ) { |
277 |
+ |
$self->verbose("Extracting Feature $param from tool". |
278 |
+ |
" (= @params )\n"); |
279 |
+ |
#$tool->setfeature($param,@params); |
280 |
+ |
$rv=1; |
281 |
+ |
} |
282 |
+ |
} |
283 |
+ |
} |
284 |
+ |
return ($rv,@params); |
285 |
+ |
} |
286 |
+ |
|
287 |
+ |
# -- Tag Routines |
288 |
+ |
|
289 |
+ |
sub Client_start { |
290 |
+ |
my $self=shift; |
291 |
+ |
my $name=shift; |
292 |
+ |
my $hashref=shift; |
293 |
+ |
|
294 |
+ |
if ( $self->{Arch} ) { |
295 |
+ |
$self->{'client'}=1; |
296 |
+ |
} |
297 |
+ |
} |
298 |
+ |
|
299 |
+ |
sub Client_end { |
300 |
+ |
my $self=shift; |
301 |
+ |
if ( $self->{Arch} ) { |
302 |
+ |
undef $self->{'client'}; |
303 |
+ |
} |
304 |
+ |
} |
305 |
+ |
|
306 |
+ |
sub Tool_Start { |
307 |
+ |
my $self=shift; |
308 |
+ |
my $name=shift; |
309 |
+ |
my $hashref=shift; |
310 |
+ |
|
311 |
+ |
$self->{switch}->checktag($name, $hashref, 'name'); |
312 |
+ |
$self->{switch}->checktag($name, $hashref, 'version'); |
313 |
+ |
$self->{switch}->opengroup("Toolactive"); |
314 |
+ |
|
315 |
+ |
# lower case the name |
316 |
+ |
$$hashref{'name'}=~tr[A-Z][a-z]; |
317 |
+ |
# make sure we only pick up the tool requested |
318 |
+ |
if ( ( $self->{tool}->name() eq $$hashref{'name'} ) && |
319 |
+ |
($self->{tool}->version() eq $$hashref{'version'})) { |
320 |
+ |
$self->{switch}-> |
321 |
+ |
allowgroup("Toolactive",$self->{switch}->currentparsename()); |
322 |
+ |
$self->{ToolEnv}{'SCRAMtoolname'}=$$hashref{'name'}; |
323 |
+ |
$self->{ToolEnv}{'SCRAMtoolversion'}=$$hashref{'version'}; |
324 |
+ |
$self->{toolfound}=0; |
325 |
+ |
} |
326 |
+ |
else { |
327 |
+ |
$self->{switch}->disallowgroup("Toolactive", |
328 |
+ |
$self->{switch}->currentparsename()); |
329 |
+ |
} |
330 |
+ |
} |
331 |
+ |
|
332 |
+ |
sub Tool_End { |
333 |
+ |
my $self=shift; |
334 |
+ |
my $name=shift; |
335 |
+ |
my $hashref=shift; |
336 |
+ |
|
337 |
+ |
$self->{switch}->closegroup("Toolactive"); |
338 |
+ |
} |
339 |
+ |
|
340 |
+ |
sub Environment_Start { |
341 |
+ |
my $self=shift; |
342 |
+ |
my $name=shift; |
343 |
+ |
my $hashref=shift; |
344 |
+ |
|
345 |
+ |
$self->{switch}->checktag($name, $hashref, 'name'); |
346 |
+ |
if ( $self->{Arch} ) { |
347 |
+ |
if ( defined $self->{EnvContext} ) { |
348 |
+ |
$self->parserror(" Attempted to open new <$name> context". |
349 |
+ |
" without closing the previous one"); |
350 |
+ |
} |
351 |
+ |
$self->{currentenvtext}=""; |
352 |
+ |
$self->{EnvContext}=$$hashref{'name'}; |
353 |
+ |
undef $self->{Envvalue}; |
354 |
+ |
if ( exists $$hashref{'type'} ) { |
355 |
+ |
$$hashref{'type'}=~tr[A-Z][a-z]; |
356 |
+ |
$self->{tool}->type($$hashref{'name'},$$hashref{'type'}); |
357 |
+ |
} |
358 |
+ |
if ( exists $$hashref{'value'}) { |
359 |
+ |
$self->{Envvalue}=$$hashref{'value'}; |
360 |
+ |
} |
361 |
+ |
elsif ( ! $self->interactive() ) { |
362 |
+ |
# check other installed copies of the tool |
363 |
+ |
my ($rv,@params)= |
364 |
+ |
$self->_toolparamcopy($self->{tool},$$hashref{'name'}); |
365 |
+ |
if ( $rv && ($#params == 0)) { #dont use multivalued params! |
366 |
+ |
$self->{Envvalue}=$params[0]; # single val parameter |
367 |
+ |
} |
368 |
+ |
elsif ( defined $ENV{$$hashref{'name'}} ) { |
369 |
+ |
# check the environment |
370 |
+ |
$self->{Envvalue}=$ENV{$$hashref{'name'}}; |
371 |
+ |
} |
372 |
+ |
elsif ( $self->_checkdefault($hashref) ) { |
373 |
+ |
$self->{Envvalue}=$$hashref{'default'}; |
374 |
+ |
} |
375 |
+ |
} |
376 |
+ |
} |
377 |
+ |
} |
378 |
+ |
|
379 |
+ |
sub Env_text { |
380 |
+ |
my $self=shift; |
381 |
+ |
my $name=shift; |
382 |
+ |
my $string=shift; |
383 |
+ |
|
384 |
+ |
if ( $self->{Arch} ) { |
385 |
+ |
$self->{currentenvtext}=$self->{currentenvtext}.$string; |
386 |
+ |
} |
387 |
+ |
} |
388 |
+ |
|
389 |
+ |
sub Environment_End { |
390 |
+ |
my $self=shift; |
391 |
+ |
my $name=shift; |
392 |
+ |
|
393 |
+ |
if ( $self->{Arch} ) { |
394 |
+ |
if ( ! defined $self->{EnvContext} ) { |
395 |
+ |
$self->{switch}->parseerror("</$name> without an opening context"); |
396 |
+ |
} |
397 |
+ |
# - set the help text |
398 |
+ |
$self->featuretext($self->{EnvContext},$self->{currentenvtext}); |
399 |
+ |
if ( ! defined $self->{Envvalue} ) { |
400 |
+ |
$self->{Envvalue}=$self->_askuser("Please Enter the Value Below:", |
401 |
+ |
$self->{EnvContext}); |
402 |
+ |
} |
403 |
+ |
$self->{Envvalue}=$self->_expandvars($self->{Envvalue}); |
404 |
+ |
$self->{tool}->addfeature($self->{EnvContext}, $self->{Envvalue}); |
405 |
+ |
$self->{ToolEnv}{$self->{EnvContext}}=$self->{Envvalue}; |
406 |
+ |
undef $self->{EnvContext}; |
407 |
+ |
undef $self->{Envvalue}; |
408 |
+ |
} |
409 |
+ |
} |
410 |
+ |
|
411 |
+ |
sub Lib { |
412 |
+ |
my $self=shift; |
413 |
+ |
my $name=shift; |
414 |
+ |
my $hashref=shift; |
415 |
+ |
|
416 |
+ |
$self->{switch}->checktag($name, $hashref, 'name'); |
417 |
+ |
if ( $self->{Arch} ) { |
418 |
+ |
$self->{tool}->addfeature("lib",$$hashref{'name'}); |
419 |
+ |
} |
420 |
+ |
} |
421 |
+ |
|
422 |
+ |
sub External_Start { |
423 |
+ |
my $self=shift; |
424 |
+ |
my $name=shift; |
425 |
+ |
my $hashref=shift; |
426 |
+ |
|
427 |
+ |
$self->{switch}->checktag($name, $hashref,'ref'); |
428 |
+ |
if ( $self->{Arch} ) { |
429 |
+ |
$self->{tool}->addfeature("_externals",$$hashref{'ref'}); |
430 |
+ |
} |
431 |
+ |
} |
432 |
+ |
|
433 |
+ |
sub Arch_Start { |
434 |
+ |
my $self=shift; |
435 |
+ |
my $name=shift; |
436 |
+ |
my $hashref=shift; |
437 |
+ |
|
438 |
+ |
$self->{switch}->checktag($name, $hashref,'name'); |
439 |
+ |
( ($ENV{SCRAM_ARCH}=~/$$hashref{name}.*/) )? ($self->{Arch}=1) |
440 |
+ |
: ($self->{Arch}=0); |
441 |
+ |
push @{$self->{ARCHBLOCK}}, $self->{Arch}; |
442 |
+ |
} |
443 |
+ |
|
444 |
+ |
sub Arch_End { |
445 |
+ |
my $self=shift; |
446 |
+ |
my $name=shift; |
447 |
+ |
|
448 |
+ |
pop @{$self->{ARCHBLOCK}}; |
449 |
+ |
$self->{Arch}=$self->{ARCHBLOCK}[$#{$self->{ARCHBLOCK}}]; |
450 |
+ |
} |
451 |
+ |
|
452 |
+ |
|