1 # Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 # All rights reserved. |
|
3 # This component and the accompanying materials are made available |
|
4 # under the terms of "Eclipse Public License v1.0" |
|
5 # which accompanies this distribution, and is available |
|
6 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 # |
|
8 # Initial Contributors: |
|
9 # Nokia Corporation - initial contribution. |
|
10 # |
|
11 # Contributors: |
|
12 # |
|
13 # Description: |
|
14 # Package: DrawSvg |
|
15 # Build the SVG diagram |
|
16 # |
|
17 # |
|
18 |
|
19 package DrawSvg; |
|
20 |
|
21 use Cwd; |
|
22 use Cwd 'abs_path'; |
|
23 use File::Copy; |
|
24 use File::Path; |
|
25 use FindBin; |
|
26 use lib $FindBin::Bin."/../common"; |
|
27 use Getopt::Long qw(:config no_ignore_case); |
|
28 use File::Basename; |
|
29 use File::Spec; |
|
30 use Logger; |
|
31 use DepConstants; |
|
32 |
|
33 |
|
34 use constant KNoCoreOs => 0; |
|
35 use constant KCoreOsWithHal => 1; |
|
36 use constant KCoreOsWithHardware => 2; |
|
37 |
|
38 my @Filters; |
|
39 |
|
40 #------------------------------------------------------------------------------------------------- |
|
41 # Subroutine: new |
|
42 # Purpose: |
|
43 # Input: None (extracted from command line args) |
|
44 # Output: A reference to itself |
|
45 #------------------------------------------------------------------------------------------------- |
|
46 sub new |
|
47 { |
|
48 my $package = shift; |
|
49 my $self = {}; # Create reference to object |
|
50 bless $self, $package; # Associate a reference with class name |
|
51 |
|
52 $self->{iScriptCode} = 999; |
|
53 |
|
54 # basic test of command line: |
|
55 if (scalar(@ARGV) == 0) |
|
56 { |
|
57 warn $self->Help(); |
|
58 &Logger::LogFatal("Incorrect syntax. Cannot continue...", $self->{iScriptCode}); |
|
59 } |
|
60 |
|
61 # process the input: |
|
62 $self->ParseCommandLineOptions(); |
|
63 |
|
64 $self->{iReturnCode} = DepConstants::KErrorNone; |
|
65 return $self; |
|
66 } |
|
67 |
|
68 |
|
69 sub GuessReleaseNumber() |
|
70 { |
|
71 my $self = shift; |
|
72 # always use release value if defined |
|
73 $self->{iRelease} && return $self->{iRelease} ; |
|
74 # if not there, it's in the s12, |
|
75 my $ver; |
|
76 my $t = $/; |
|
77 foreach my $s12 (@{$self->{'iS12'}}) # use version from first s12 file listed |
|
78 { |
|
79 if(-d $s12) {next} |
|
80 open(FILE,$s12) || return; |
|
81 $/='>'; |
|
82 while(<FILE>) |
|
83 { |
|
84 if(/<Schedule12\s.*\bOS_version=('(.*?)'|"(.*?)")/s) |
|
85 { |
|
86 $ver = $2 || $3; |
|
87 last; |
|
88 } |
|
89 } |
|
90 close FILE; |
|
91 $/=$t; |
|
92 return $ver; |
|
93 } |
|
94 # not there either, |
|
95 if($self->{'iDepsFile'}) |
|
96 { |
|
97 open(FILE,$self->{'iDepsFile'}) || return; |
|
98 $/='>'; |
|
99 while(<FILE>) |
|
100 { |
|
101 if(/<SystemModelDeps\s.*\bversion=('(.*?)'|"(.*?)")/s) |
|
102 { |
|
103 $ver = $2 || $3; |
|
104 last; |
|
105 } |
|
106 } |
|
107 close FILE; |
|
108 $/=$t; |
|
109 return $ver; |
|
110 } |
|
111 return ""; |
|
112 } |
|
113 |
|
114 |
|
115 # an empty value indicates its a single file. Any other value means it's a list separated by that value as a regexp |
|
116 %KFileParams = |
|
117 ( |
|
118 'iSysDefFile' => ',', |
|
119 'iS12' => ',', |
|
120 'iExtra' => ',', |
|
121 'iDepsFile' => '', |
|
122 'iLocalize' => ',', |
|
123 'iLevels' => ',', |
|
124 'iStyle' => ',', |
|
125 'iOverlay' => ',', |
|
126 'iBorder' => ',', |
|
127 'iColor' => ',', |
|
128 'iShapes' => '', |
|
129 'iLogoSrc' => '', |
|
130 'iModel' => '', |
|
131 'iLogFile' => '', |
|
132 ); |
|
133 |
|
134 sub ParseCommandLineOptions() |
|
135 { |
|
136 my $self = shift; |
|
137 |
|
138 # Possible arguments (with default values where possible): |
|
139 my $help; |
|
140 $self->{iSysDefFile}; |
|
141 $self->{iDepsFile}; |
|
142 $self->{iOutputCsv}; |
|
143 $self->{iCsvColumns}; |
|
144 $self->{iCsvLabels}; |
|
145 $self->{iTemporaryDirectory}; |
|
146 $self->{iLogFile}; |
|
147 $self->{iWarningLevel}; |
|
148 $self->{iClean}; # if specified, it will delete the temp directory. |
|
149 |
|
150 # custom properties: |
|
151 $self->{iDiagram}; # the output svg |
|
152 $self->{iCopyright}; |
|
153 $self->{iRelease}; |
|
154 $self->{iName}; |
|
155 $self->{iLabel}; |
|
156 $self->{iModel}; |
|
157 $self->{iCoreOs}; |
|
158 $self->{iLevels}; |
|
159 $self->{iExtra}; |
|
160 $self->{iIniFile}; |
|
161 $self->{iS12}; |
|
162 $self->{iLink}; |
|
163 # Read in the user arguments: |
|
164 GetOptions( "h" => \$help, |
|
165 "i=s" => \$self->{iIniFile}, |
|
166 "output=s" => \$self->{iDiagram} , |
|
167 "csv_output=s" => \$self->{iOutputCsv} , |
|
168 "csv_columns=s" => \$self->{iCsvColumns} , |
|
169 "csv_labels=s" => \$self->{iCsvLabels} , |
|
170 'xml_output=s' => \$self->{iOutputXml} , |
|
171 "model=s" => \$self->{iModel} , |
|
172 "sysdef=s" => \@{$self->{iSysDefFile}} , |
|
173 "srcvar=s" => \@{$self->{iSourceRoot}} , |
|
174 "shapes=s" => \$self->{iShapes}, |
|
175 "link=s" => \$self->{iLink}, |
|
176 "system_name=s" => \$self->{iName} , |
|
177 "system_version=s" => \$self->{iRelease} , |
|
178 "model_name=s" => \$self->{iLabel} , |
|
179 "model_version=s" => \$self->{iRevision}, |
|
180 "model_version_type=s" => \$self->{iRevisionType}, |
|
181 "copyright=s" => \$self->{iCopyright}, |
|
182 "distribution=s" => \$self->{iDistribution}, |
|
183 "coreos=s" => \$self->{iCoreOs}, |
|
184 |
|
185 "sysinfo=s" => \@{$self->{iExtra}}, |
|
186 "localize=s" => \@{$self->{iLocalize}}, |
|
187 "levels=s" => \@{$self->{iLevels}}, |
|
188 |
|
189 "color=s" => \@{$self->{iColor}}, |
|
190 "border-shape=s" => \@{$self->{iBorder}}, |
|
191 "pattern=s" => \@{$self->{iOverlay}}, |
|
192 "border-style=s" => \@{$self->{iStyle}}, |
|
193 |
|
194 "filter=s" => \@{$self->{iFilter}}, |
|
195 "filter-has=s" => \&OrderedOption, |
|
196 "show-attr=s" => \&OrderedOption, |
|
197 "hide-attr=s" => \&OrderedOption, |
|
198 "ignore=s" => \@{$self->{iIgnore}}, |
|
199 |
|
200 "s12=s" => \@{$self->{iS12}}, |
|
201 |
|
202 "detail=s" => \$self->{iDetail}, |
|
203 "detail-type=s" => \$self->{iDetailType}, |
|
204 "page-width=s" => \$self->{iPageWidth}, |
|
205 "static" => \$self->{iStatic}, |
|
206 "deps=s" => \$self->{iDepsFile}, |
|
207 "w=s" => \$self->{iWarningLevel}, |
|
208 "clean" => \$self->{iClean}, |
|
209 "compress" => \$self->{iCompress}, |
|
210 "tempdir=s" => \$self->{iTemporaryDirectory}, |
|
211 "dpi=s" => \$self->{iPrintResolution}, |
|
212 "model_font=s" => \$self->{iModelFont}, |
|
213 "version-list=s" => \$self->{iVersions}, |
|
214 "log=s" => \$self->{iLogFile}, |
|
215 "logo=s" => \$self->{iLogoSrc}, |
|
216 "logo-height=s" => \$self->{iLogoHeight}, |
|
217 "logo-width=s" => \$self->{iLogoWidth}, |
|
218 "legend-width=s" => \$self->{iLegendWidth}, |
|
219 "legend-max-scale=s" => \$self->{iLegendMaxScale}, |
|
220 "title-scale=s" => \$self->{iTitleScale}, |
|
221 "xslt-param=s" => \%{$self->{iXsltParam}}, |
|
222 "note=s" => \@{$self->{iLegendNote}} |
|
223 ); |
|
224 |
|
225 if ($help) |
|
226 { |
|
227 warn $self->Help(); |
|
228 exit DepConstants::KErrorNone; |
|
229 } |
|
230 |
|
231 @{$self->{'iFiltering'}} = @Filters; |
|
232 @Filters=(); |
|
233 my $i=0; |
|
234 for($i=0;$i<=$#ARGV;$i++) |
|
235 { # check remaining args to ensure they are valid |
|
236 if($ARGV[$i]=~/^(http|file):\/\//) { # assume URLs are correct |
|
237 next; |
|
238 } |
|
239 if($ARGV[$i] eq "-" || $ARGV[$i] eq "") |
|
240 { #special values to use nothing or use the tmp file, but only valid for odd numbered args |
|
241 if($i%2==1) {next} |
|
242 warn "Invalid syntax"; |
|
243 warn $self->Help(); |
|
244 exit DepConstants::KIncorrectSyntax |
|
245 } |
|
246 if(!(-e $ARGV[$i])) { |
|
247 warn "file $ARGV[$i] does not exist"; |
|
248 exit DepConstants::KFileDoesNotExist; |
|
249 } |
|
250 } |
|
251 |
|
252 # Now read the ini file and override command line if necessary: |
|
253 my @yr = gmtime(); |
|
254 my $dataroot =&DepConstants::SystemModelXmlDataDir(); |
|
255 my %defaults = ( |
|
256 'iCopyright' => (1900+$yr[5])." Nokia Corporation", |
|
257 'iDiagram' => "sysmodel.svg", |
|
258 'iTemporaryDirectory' => "drawsvg_temp", |
|
259 'iName' => "Symbian OS" , |
|
260 'iLabel' => "System Model", |
|
261 'iShapes' => "$dataroot/Shapes.xml" , |
|
262 'iLogFile' => "" # do not set this to any default: stdout is used if log file isn't set |
|
263 ); |
|
264 my %defaultsForMulti = ( |
|
265 'iLocalize' => "$dataroot/display-names.xml" , |
|
266 'iExtra' => "$dataroot/SystemInfo.xml" |
|
267 ); |
|
268 |
|
269 $self->ReadIniFile(); |
|
270 |
|
271 foreach my $type ('iSysDefFile', 'iFilter','iSourceRoot') |
|
272 { |
|
273 if(scalar(@{$self->{$type}})==1 && $self->{$type}->[0]=~/,/) |
|
274 { # treat as comma-separated for backwards compatibility (leave alone if no commas) |
|
275 @{$self->{$type}} = split(/,/,$self->{$type}->[0]); |
|
276 } |
|
277 } |
|
278 if (scalar(@{$self->{iIgnore}})) |
|
279 { |
|
280 foreach my $type ('iIgnore') |
|
281 { |
|
282 if(scalar(@{$self->{$type}})==1) |
|
283 { # treat as semicolon-separated for backwards compatibility |
|
284 @{$self->{$type}} = split(/;/,$self->{$type}->[0]); |
|
285 } |
|
286 } |
|
287 } |
|
288 else |
|
289 { |
|
290 push(@{$self->{iIgnore}}, "layer:Tools and Utils and SDKENG","layer:MISC","block:Techview") |
|
291 } |
|
292 |
|
293 |
|
294 my $ver = $self->GuessReleaseNumber(); # determine release from attached files. |
|
295 |
|
296 # Use a special levels.xml file for 9.1 (unless it's specified by the user): |
|
297 push(@{$self->{iLevels}}, "$dataroot/Levels91.xml") if !scalar(@{$self->{iLevels}}) and $ver eq "9.1"; |
|
298 push(@{$self->{iLevels}}, "$dataroot/Levels.xml") if !scalar(@{$self->{iLevels}}) and ($ver eq "9.2" or $ver eq "9.2" ); |
|
299 |
|
300 if(!scalar(@{$self->{'iFiltering'}}) && !scalar(@{$self->{'iFilter'}})) |
|
301 { # filter only has a default if fitler-has is not set |
|
302 @{$self->{'iFilter'}}= ("java","gt"); |
|
303 } |
|
304 while (($key, $value) = each %defaults) { |
|
305 $self->{$key} = $value if ! defined $self->{$key}; |
|
306 } |
|
307 |
|
308 while (($key, $value) = each %defaultsForMulti) { |
|
309 push(@{$self->{$key}}, $value) if ! scalar(@{$self->{$key}}); |
|
310 } |
|
311 |
|
312 |
|
313 |
|
314 # if saving to .svgz, try to compress |
|
315 $self->{iCompress} = $self->{iCompress} || ( $self->{iDiagram} =~ /\.svgz$/i ); |
|
316 |
|
317 # if there's a deps file XSLT will get revision number and type from that. |
|
318 # if there is no deps file and neither revision nor revision type are specified, default to "DRAFT 1" |
|
319 if(!$self->{'iDepsFile'} && !$self->{'iRevision'} && !$self->{'iRevisionType'}) |
|
320 { |
|
321 $self->{'iRevisionType'} = "draft"; |
|
322 $self->{'iRevision'} = "1"; |
|
323 } |
|
324 |
|
325 if ($self->{iShapes} eq "$dataroot/Shapes.xml" && !scalar(@{$self->{'iColor'}})) |
|
326 { # if it's got the default shapes use default colours |
|
327 @{$self->{iColor}} = (&DepConstants::SystemModelColorsXmlFile()); |
|
328 } |
|
329 |
|
330 if(defined $self->{iCoreOs}) |
|
331 { |
|
332 if($self->{iCoreOs}=~/(on|yes|true)$/i ) |
|
333 { |
|
334 $self->{iCoreOs} = KCoreOsWithHal; |
|
335 } |
|
336 elsif($self->{iCoreOs}=~/(off|no|false)$/i ) |
|
337 { |
|
338 $self->{iCoreOs} = KNoCoreOs; |
|
339 } |
|
340 elsif(! ($self->{iCoreOs}=~/^[0-9]+$/ )) # any other non-number |
|
341 { |
|
342 $self->{iCoreOs} = KCoreOsWithHardware; |
|
343 } |
|
344 } |
|
345 else # use version numebr to decide |
|
346 { |
|
347 $self->{iCoreOs} = ($self->{iRelease} eq 'Future' || $ver > 9.4) ? KCoreOsWithHardware : |
|
348 (($ver=~/^9\.4/) ? KCoreOsWithHal : KNoCoreOs); |
|
349 } |
|
350 |
|
351 $self->{'iGuessVer'} = $ver; |
|
352 |
|
353 mkpath $self->{iTemporaryDirectory} if ! -d $self->{iTemporaryDirectory}; |
|
354 |
|
355 # set the log file if needed: |
|
356 $Logger::LOGFILE = $self->{iLogFile} if $self->{iLogFile}; |
|
357 |
|
358 # set the correct warning level: |
|
359 # -w=1: errors only (default) |
|
360 # -w=2: warnings as well as errors |
|
361 # -w=3: info messages, warnings and errors. |
|
362 if (defined $self->{iWarningLevel} and $self->{iWarningLevel} > 1) |
|
363 { |
|
364 if ($self->{iWarningLevel} == 2) |
|
365 { |
|
366 $self->{iWarningLevel} = DepConstants::WARNING; |
|
367 } |
|
368 elsif ($self->{iWarningLevel} == 3) |
|
369 { |
|
370 $self->{iWarningLevel} = DepConstants::INFO; |
|
371 } |
|
372 else # for anything higher than set it to DepConstants::VERBOSE |
|
373 { |
|
374 $self->{iWarningLevel} = DepConstants::VERBOSE; |
|
375 } |
|
376 } |
|
377 else |
|
378 { |
|
379 $self->{iWarningLevel} = DepConstants::ERROR; |
|
380 } |
|
381 # set the logger up: |
|
382 $Logger::SEVERITY = $self->{iWarningLevel}; |
|
383 |
|
384 # set all URIs |
|
385 |
|
386 (my $dir = cwd ) =~ s#\/#\\#g; |
|
387 |
|
388 |
|
389 foreach ( keys(%KFileParams)) { |
|
390 if($self->{$_} eq '') {next} # no value, so do nothing |
|
391 if($KFileParams{$_} eq '') { |
|
392 $self->{$_} = &FullPath("$dir\\", $self->{$_} ); |
|
393 } elsif($KFileParams{$_} eq ',') { |
|
394 foreach my $item (@{$self->{$_}}) { |
|
395 if ($item eq '') {next} # skip if explicitly set to empty |
|
396 $item = &FileAsUrl(&FullPath("$dir\\",$item)); |
|
397 } |
|
398 next; |
|
399 } |
|
400 $self->{$_} = &FileAsUrl($self->{$_}); |
|
401 } |
|
402 |
|
403 } |
|
404 |
|
405 |
|
406 sub OrderedOption() { |
|
407 my $var = shift; |
|
408 my $val = shift; |
|
409 if($var=~/^(show|hide)-attr$/) { |
|
410 my $f = "<filter display='$1' "; |
|
411 if($val=~s/^([^=]+)=//) {$f.="select='$1' value='$val'/>"} |
|
412 else {$f.="select='$val'/>"} |
|
413 push(@Filters,$f); |
|
414 } elsif($var eq 'filter-has' && $val eq '*') { |
|
415 push(@Filters,"<filter display='show' select='*'/>"); |
|
416 }elsif($var eq 'filter-has') { |
|
417 if(!scalar(@Filters)) { # if the 1st is showing a filter than that implies everythig without a filter is turned off |
|
418 push(@Filters,'<filter select="*" display="hide"/>'); |
|
419 } |
|
420 foreach my $v (split(/,/,$val)) { |
|
421 push(@Filters,"<filter display='show' select='filter' value='$v'/>"); |
|
422 } |
|
423 } |
|
424 } |
|
425 |
|
426 |
|
427 |
|
428 sub FullPath { |
|
429 my $root = shift; |
|
430 my $file = shift; |
|
431 |
|
432 # If the file is not specified then return null |
|
433 if (!$file) { |
|
434 return; |
|
435 } |
|
436 |
|
437 |
|
438 # If the file is a URL or Windows path then return it as is |
|
439 if ($file =~ /:/) { |
|
440 return $file; |
|
441 } |
|
442 |
|
443 if ($root && !-e $root) { |
|
444 &Logger::LogFatal("$root does not exist"); |
|
445 } |
|
446 |
|
447 if (-f $root) { |
|
448 $root = File::Basename::dirname($root) |
|
449 } |
|
450 |
|
451 # if root is empty or the same dir, then file is relative |
|
452 if($root eq '' or $root eq '.') { |
|
453 return $file; |
|
454 } |
|
455 |
|
456 # If the file is relative from the root then we want to add the drive letter to the file (if one exists) |
|
457 if ($file =~ s/^[\\\/]// ) { |
|
458 if ($root =~ /^([a-z]:)/i) { |
|
459 return File::Spec->catdir($1, $file); |
|
460 } |
|
461 } |
|
462 |
|
463 # Return the concatenated root and filename |
|
464 return File::Spec->catdir($root, $file); |
|
465 } |
|
466 |
|
467 |
|
468 sub ReadIniFile() |
|
469 { |
|
470 my $self = shift; |
|
471 |
|
472 return if ! defined $self->{iIniFile}; |
|
473 |
|
474 # Log a fatal error if the ini file is defined but doesn't exist: |
|
475 &Logger::LogFatal("ini file does not exist\"$self->{iIniFile}\": $!", $self->{iScriptCode}) if ! -e $self->{iIniFile}; |
|
476 |
|
477 open(INI, $self->{iIniFile}) or |
|
478 &Logger::LogFatal("Could not open the ini file \"$self->{iIniFile}\": $!", $self->{iScriptCode}); |
|
479 |
|
480 &Logger::LogInfo("Reading ini file \"$self->{iIniFile}...", $self->{iScriptCode}); |
|
481 |
|
482 %AllowMulitples = ( |
|
483 "iLocalize" => 1, |
|
484 "iExtra" => 1, |
|
485 'iLevels' => 1, |
|
486 'iSysDefFile' => 1, |
|
487 'iSourceRoot' => 1, |
|
488 'iS12' => 1, |
|
489 "iIgnore" => 1, |
|
490 "iFilter" => 1, |
|
491 "iStyle" => 1, |
|
492 "iOverlay" => 1, |
|
493 "iBorder" => 1, |
|
494 "iColor" => 1, |
|
495 "iLegendNote" => 1, |
|
496 "iXsltParam" => 2 |
|
497 ); # value of 2 means it's a hash, value of 1 is an array |
|
498 |
|
499 foreach my $m (keys %AllowMulitples) { |
|
500 # if it's already set, note that we're to ignore anything in the ini file |
|
501 if($AllowMulitples{$m}==2 ? (scalar(%{$self->{$m}})>0) : (scalar(@{$self->{$m}})>0)) {$AllowMulitples{$m}=0} |
|
502 } |
|
503 |
|
504 %Ordered = ( |
|
505 "filter-has" => 1, |
|
506 "show-attr" => 1, |
|
507 "hide-attr" => 1 |
|
508 ); |
|
509 |
|
510 %IniMap = ( |
|
511 "model" => 'iModel' , |
|
512 "sysdef" => 'iSysDefFile' , |
|
513 'srcvar' => 'iSourceRoot', |
|
514 "shapes" => 'iShapes', |
|
515 "system_name" => 'iName' , |
|
516 "model_name" => 'iLabel' , |
|
517 "system_version" => 'iRelease' , |
|
518 "copyright" => 'iCopyright', |
|
519 "model_version" => 'iRevision', |
|
520 "model_version_type" => 'iRevisionType', |
|
521 "distribution" => 'iDistribution', |
|
522 "coreos" => 'iCoreOs', |
|
523 "sysinfo" => 'iExtra', |
|
524 "localize" => 'iLocalize', |
|
525 "levels" => 'iLevels', |
|
526 "filter" => 'iFilter', |
|
527 "ignore" => 'iIgnore', |
|
528 "output" => 'iDiagram', |
|
529 "csv_output" => 'iOutputCsv', |
|
530 "csv_columns" => 'iCsvColumns' , |
|
531 "csv_labels" => 'iCsvLabels' , |
|
532 'xml_output' => 'iOutputXml' , |
|
533 "detail" => 'iDetail', |
|
534 "detail-type" => 'iDetailType', |
|
535 "page-width" => 'iPageWidth', |
|
536 "static" => 'iStatic', |
|
537 "color" => 'iColor', |
|
538 "border-shape" => 'iBorder', |
|
539 "pattern" => 'iOverlay', |
|
540 "deps" => 'iDepsFile', |
|
541 "border-style" => 'iStyle', |
|
542 "w" => 'iWarningLevel', |
|
543 "tempdir" => 'iTemporaryDirectory', |
|
544 'dpi' =>'iPrintResolution', |
|
545 'model_font' =>'iModelFont', |
|
546 "s12" => 'iS12', |
|
547 "log" => 'iLogFile', |
|
548 "logo" => 'iLogoSrc', |
|
549 "logo-height" => 'iLogoHeight', |
|
550 "logo-width" => 'iLogoWidth', |
|
551 'version-list' => 'iVersions', |
|
552 "link" => 'iLink', |
|
553 "clean" => 'iClean', |
|
554 "compress" => 'iCompress', |
|
555 "legend-width" =>'iLegendWidth', |
|
556 "legend-max-scale" => 'iLegendMaxScale', |
|
557 "title-scale" => 'iTitleScale', |
|
558 "xslt-param" => 'iXsltParam', |
|
559 "note" => 'iLegendNote' |
|
560 ); |
|
561 |
|
562 foreach my $line (<INI>) |
|
563 { |
|
564 $line =~ s/^\s*//; # remove spaces |
|
565 $line =~ s/\s*$//; # a/a |
|
566 $line =~ s/\n$//; # remove new line |
|
567 if($line =~/"/) { |
|
568 $line =~ s/^(([^"#]*"[^"]*")+)#.*$/$1/; # remove comments indicated by # (to the end of the line) |
|
569 } else { |
|
570 $line =~ s/#.*$//; # remove comments indicated by # (to the end of the line) |
|
571 } |
|
572 next if $line eq ""; # ignore blank lines |
|
573 if ($line =~ m/([^=]+)\s*=\s*(.*)/) |
|
574 { |
|
575 my $argType = lc $1; # case-insensitive |
|
576 my $argValue = $2; # case-sensitive as it can have strings intended for html output |
|
577 |
|
578 $argType =~ s/^\s*//; # remove spaces on either end (Cannot use s/\s+// as this will not be suitable for html text) |
|
579 $argType =~ s/\s*$//; |
|
580 $argValue =~ s/^\s*//; |
|
581 $argValue =~ s/\s*$//; |
|
582 |
|
583 $argValue =~ s/^'//; # no need for quotes around the values |
|
584 $argValue =~ s/'$//; |
|
585 $argValue =~ s/^"//; |
|
586 $argValue =~ s/"$//; |
|
587 |
|
588 my $iniDir = $self->{iIniFile}; |
|
589 $iniDir =~ s,[^\\//]+$,,; |
|
590 #$iniDir .= '\\'; |
|
591 |
|
592 if(defined $Ordered{$argType}) { |
|
593 &OrderedOption($argType, $argValue); |
|
594 } elsif(defined $IniMap{$argType}) { |
|
595 my $param = $IniMap{$argType}; |
|
596 # make sure all files mentioned are taken relative to the ini file |
|
597 if($KFileParams{$param} ne '' ) |
|
598 {# comma-separated filenames |
|
599 my @list; |
|
600 foreach my $item (split(/,/,$argValue)) |
|
601 { |
|
602 push(@list,&FullPath($iniDir,$item)); |
|
603 } |
|
604 $argValue = join(',',@list); |
|
605 } |
|
606 elsif(defined $KFileParams{$param} && $argValue ne '') |
|
607 {# single file names |
|
608 $argValue = &FullPath($iniDir,$argValue); |
|
609 } |
|
610 # do not override! Only set values that have not been set on command line already |
|
611 if ($AllowMulitples{$param}==1) # check so we don't add if it's set by the cmd line |
|
612 { |
|
613 push(@{$self->{$param}}, $argValue); |
|
614 } |
|
615 elsif ($AllowMulitples{$param}==2) # check so we don't add if it's set by the cmd line |
|
616 { |
|
617 $argValue=~s/^([^=]+)=//; |
|
618 $self->{$param}->{$1}=$argValue; |
|
619 } |
|
620 elsif (! defined $AllowMulitples{$param}) |
|
621 { |
|
622 $self->{$param} = $argValue if ! $self->{$param}; |
|
623 } |
|
624 } |
|
625 } |
|
626 } |
|
627 ; |
|
628 @{$self->{'iFiltering'}} = @Filters if ! @{$self->{'iFiltering'}}; |
|
629 @Filters=(); |
|
630 } |
|
631 |
|
632 sub MakeInfo() { |
|
633 my $self = shift; |
|
634 my %files = @_; |
|
635 my $res=""; |
|
636 while (my ($key,$value) = each %files) { |
|
637 if ($self->{$key} ne '') { |
|
638 $res .= "\t\t<info href='".$self->{$key}."' type='$value'/>\n" |
|
639 } |
|
640 } |
|
641 return $res; |
|
642 } |
|
643 |
|
644 sub MakeMultiInfo() { |
|
645 my $self = shift; |
|
646 my %files = @_; |
|
647 my $res=""; |
|
648 while (my ($key,$value) = each %files) { |
|
649 foreach my $m (@{$self->{$key}}) { |
|
650 if($m ne '') { # skip if empty |
|
651 $res .= "\t\t<info href='$m' type='$value'/>\n" |
|
652 } |
|
653 } |
|
654 } |
|
655 return $res; |
|
656 } |
|
657 |
|
658 sub MakeAttirbutes() { |
|
659 my $self = shift; |
|
660 my %atts = @_; |
|
661 my $res=""; |
|
662 while (my ($key,$value) = each %atts) { |
|
663 if (defined $self->{$key}) { |
|
664 my $cur = $self->{$key}; |
|
665 if($key=~/File$/) {$cur=&FileAsUrl($cur)} # anything that ends in File is treated as a URL |
|
666 $res .= " $value=\"$cur\""; |
|
667 } |
|
668 } |
|
669 return $res; |
|
670 } |
|
671 |
|
672 sub getSchedule12Xml () |
|
673 { |
|
674 my $self = shift; |
|
675 my $ver = shift; |
|
676 my @files = @{$self->{'iS12'}}; |
|
677 my @ret; |
|
678 foreach my $s12 (@files) |
|
679 { |
|
680 if($s12 eq '') {next} |
|
681 if($s12=~/^file:\/\/\/(.*)$/) |
|
682 { |
|
683 if(-d $1) |
|
684 { |
|
685 # it's a directory, so append Symbian_OS_v[version]_Schedule12.xml |
|
686 $s12=~s,[\\/]*$,/Symbian_OS_v${ver}_Schedule12.xml,; |
|
687 } |
|
688 } |
|
689 push(@ret,$s12); |
|
690 } |
|
691 return @ret |
|
692 } |
|
693 |
|
694 sub getModel() |
|
695 { |
|
696 my $self = shift; |
|
697 if($self->{iModel}) {return $self->{iModel}} |
|
698 |
|
699 my $xsltDir = $self->GetXsltDir(); |
|
700 |
|
701 my $tempDirectoryPathname = abs_path($self->{iTemporaryDirectory}); |
|
702 |
|
703 (my $modelXml = "$tempDirectoryPathname/Model.xml") =~ s#\/#\\#g; |
|
704 (my $modelTemplateXml = $xsltDir."/") =~ s#\/#\\#g; |
|
705 |
|
706 if($self->{iCoreOs} == KCoreOsWithHardware) { # show 9.5+ CoreOS |
|
707 $modelTemplateXml .= "ModelTemplate.xml"; |
|
708 } elsif($self->{iCoreOs} == KCoreOsWithHal ) { # show 9.4 CoreOS |
|
709 $modelTemplateXml .= "ModelTemplate.mid.xml"; |
|
710 } else { |
|
711 $modelTemplateXml .= "ModelTemplate.older.xml"; |
|
712 } |
|
713 |
|
714 |
|
715 # the follownig params cannot be emtpy, delete if they are |
|
716 foreach my $item ('iCopyright' , 'iDistribution' ,'iDepsFile', 'iLink', 'iDetailType', 'iDetail', 'iVersions') |
|
717 { |
|
718 if($self->{$item} eq '') {delete $self->{$item}} |
|
719 } |
|
720 |
|
721 |
|
722 # Step 1: |
|
723 # Create a Model.xml based on the ModelTemplate.xml |
|
724 open (INPUT, $modelTemplateXml) or &Logger::LogError("Xalan error ($error) occured in Step 1 of SVG building...", $self->{iScriptCode}, 1); |
|
725 open (OUTPUT, ">$modelXml") or &Logger::LogError("Xalan error ($error) occured in Step 1 of SVG building...", $self->{iScriptCode}, 1); |
|
726 my $release = $self->{iRelease}; |
|
727 |
|
728 |
|
729 |
|
730 # Since $self->{iSysDefFile} may be a comma-separated list of sysdefs, create a <sysdef> tag for each one of the files: |
|
731 my $sysdefTagsForModelTemplate = ""; |
|
732 |
|
733 @{$self->{'iS12'}} = $self->getSchedule12Xml($self->{'iGuessVer'}); |
|
734 |
|
735 if(scalar(@{$self->{iSourceRoot}}) == 1) |
|
736 { |
|
737 @{$self->{iSourceRoot}} = ($self->{iSourceRoot}->[0]) x scalar($self->{iSourceRoot}->[0]); |
|
738 } |
|
739 |
|
740 for (my $index = 0; $index < scalar(@{$self->{iSysDefFile}}); ++$index) |
|
741 { |
|
742 $sysdefTagsForModelTemplate .= $self->CreateSysDefTagsForModelXML($self->{iSysDefFile}->[$index], $self->{iSourceRoot}->[$index]); |
|
743 } |
|
744 |
|
745 my $display; |
|
746 |
|
747 if($self->{iLink}=~/\\/) # it's a windows dir, change to file URI |
|
748 { |
|
749 $self->{iLink} = &FileAsUrl($self->{iLink}); |
|
750 } |
|
751 |
|
752 $display .= $self->MakeMultiInfo ('iLocalize' => 'abbrev'); |
|
753 |
|
754 my %infoMap = ( |
|
755 'iStyle' => 'style', |
|
756 'iOverlay' => 'overlay', |
|
757 'iBorder' => 'border', |
|
758 'iColor' => 'color' |
|
759 ); |
|
760 |
|
761 $display .=$self->MakeMultiInfo( %infoMap); |
|
762 if($self->{'iLogoSrc'}) |
|
763 { |
|
764 $display.="\n<logo". $self->MakeAttirbutes( |
|
765 'iLogoSrc' => 'src', |
|
766 'iLogoWidth' => 'width', |
|
767 'iLogoHeight' => 'height' |
|
768 ) ; |
|
769 if($self->{'iLogoSrc'} =~ /\.svg$/i) |
|
770 { |
|
771 $display.= " embed=\"yes\""; |
|
772 } |
|
773 $display.= "/>"; |
|
774 } |
|
775 |
|
776 my $filters=''; |
|
777 if(scalar @{$self->{'iFiltering'}}) # complex filtering |
|
778 { |
|
779 $filters = join("\n\t",@{$self->{'iFiltering'}}); |
|
780 } |
|
781 elsif (@{$self->{iFilter}}) { # can't have both -filter and complex filtering |
|
782 foreach ( @{$self->{iFilter}}) { |
|
783 if($_ ne '') {$filters.="<filter accept='$_'/>\n\t";} |
|
784 } |
|
785 } |
|
786 |
|
787 my $ignore=''; |
|
788 |
|
789 foreach ( @{$self->{iIgnore}}){ |
|
790 if(/^(.*):(.*)$/) {$ignore.="<ignore type='$1' name='$2'/>\n\t"} |
|
791 } |
|
792 |
|
793 |
|
794 my $optional = $self->MakeAttirbutes( |
|
795 'iCopyright' => 'copyright', |
|
796 'iDistribution' => 'distribution', |
|
797 'iRevision' => 'revision', |
|
798 'iDepsFile' => 'deps', |
|
799 'iLink' => 'link', |
|
800 'iRevisionType' => 'revision-type', |
|
801 'iVersions' => 'version-list' |
|
802 ); |
|
803 |
|
804 if($self->{iRelease} ne '') {$optional .= " ver='$self->{iRelease}'"} |
|
805 elsif($self->{iGuessVer} eq 'Future' ) {$optional .= " ver='$self->{iGuessVer}'"} |
|
806 |
|
807 |
|
808 my $layout = $self->MakeAttirbutes( |
|
809 'iDetail' => 'detail', |
|
810 'iDetailType' => 'detail-type', |
|
811 'iPageWidth' => 'page-width', |
|
812 'iPrintResolution' => 'resolution', |
|
813 'iModelFont' => 'font' |
|
814 ); |
|
815 if($self->{iStatic}) {$layout .= " static='true'"} |
|
816 my $legend = ''; |
|
817 my @legendmap = ( |
|
818 'iColor', 'colors', |
|
819 'iStyle', 'styles', |
|
820 'iOverlay', 'patterns', |
|
821 'iBorder', 'borders' |
|
822 ); # order is important |
|
823 for(my $i=0; $i<$#legendmap;$i+=2){ |
|
824 my $cur='#'.$infoMap{$legendmap[$i]}; |
|
825 my $count = scalar(@{$self->{$legendmap[$i]}}); |
|
826 if ($count==0 || ($count==1 && $self->{$legendmap[$i]}->[0] eq '' )) {$cur='@shapes'."#$legendmap[$i+1]"} |
|
827 $legend .= "\t\t\t<legend use=\"$cur\"/>\n"; |
|
828 } |
|
829 foreach my $note (@{$self->{iLegendNote}}) |
|
830 { |
|
831 if(!($note=~/&#?[0-9a-z]+;/i)) |
|
832 { # if not entity-encoded, entity encode the stuff |
|
833 $note=~ s/([&<>\x7f-\xff])/"&#".ord($1).";"/eg; |
|
834 } |
|
835 $legend .= "\t\t\t<note width='auto'>$note</note>"; |
|
836 } |
|
837 |
|
838 my $legendOptions; |
|
839 if($self->{iLegendWidth}) {$legendOptions .= ' width="' .$self->{iLegendWidth} .'"'} |
|
840 if($self->{iLegendMaxScale}) {$legendOptions .= ' maxscale="' .$self->{iLegendMaxScale} .'"'} |
|
841 if($self->{iTitleScale}) {$legendOptions .= ' title-scale="' .$self->{iTitleScale} .'"'} |
|
842 foreach my $line (<INPUT>) |
|
843 { |
|
844 my $cur=''; |
|
845 $line =~ s/___SYMBIAN_OS_RELEASE___/$self->{iRelease}/g; # not used |
|
846 $line =~ s/___NAME___/$self->{iName}/g; |
|
847 $line =~ s/___LABEL___/$self->{iLabel}/g; |
|
848 $line =~ s/___REVISION_TYPE___/$self->{iRevisionType}/g; # not used |
|
849 $line =~ s/___LINK___/$self->{iLink}/g; # not used |
|
850 $line =~ s/___OPTIONAL___/$optional/g; |
|
851 $line =~ s/___LAYOUT_OPTIONS___/$layout/g; |
|
852 $line =~ s/___FILTERS___/$filters/g; |
|
853 $line =~ s/___IGNORE___/$ignore/g; |
|
854 $line =~ s/___LEGEND___/$legend/g; |
|
855 $line =~ s/___LEGEND_OPTIONS___/$legendOptions/g; |
|
856 $line =~ s/___SHAPES_XML___/$self->{iShapes}/g; |
|
857 $line =~ s/___SYSTEM_DEFINITIONS___/$sysdefTagsForModelTemplate/; # should be only one incident of it |
|
858 $line =~ s/___DISPLAY___/$display/g; |
|
859 $line =~ s/\sshapes=""//g; # remove empty attribute |
|
860 print OUTPUT $line; |
|
861 } |
|
862 close INPUT; |
|
863 close OUPUT; |
|
864 |
|
865 # Open and close the file so that it can flush itself: |
|
866 open (OUTPUT, "$modelXml") or &Logger::LogError("Xalan error ($error) occured in Step 1 of SVG building...", $self->{iScriptCode}, 1); |
|
867 close OUTPUT; |
|
868 return $modelXml; |
|
869 } |
|
870 |
|
871 sub GetXsltDir() |
|
872 { |
|
873 my $self = shift; |
|
874 my $xsltDir = $FindBin::Bin."/svg"; # calcluated w.r.t root of Dep directory |
|
875 $xsltDir = $FindBin::Bin."/../svg" if ! -d $xsltDir; # calculated w.r.t the /commands directory |
|
876 return $xsltDir; |
|
877 } |
|
878 |
|
879 |
|
880 sub FileAsUrl() |
|
881 { |
|
882 my $file = $_[0]; |
|
883 if($file=~/^..+:/){ return $file} # already a URL |
|
884 if(-f $file) |
|
885 { # abs_path only works on dirs, so strip off file name and put it back when done |
|
886 if(! ($file=~/^[a-z]:[\\\/][^\\\/]+$/i)) |
|
887 { # if it's in the root dir, do nothing |
|
888 my $tail = "/$file"; |
|
889 # if it's just a file name, need to find cwd; |
|
890 if($file =~ s,([\\/][^\\/]+)$,,) |
|
891 { |
|
892 $tail = $1; |
|
893 } |
|
894 else {$file = "."} |
|
895 $file = abs_path($file)."$tail"; |
|
896 } |
|
897 } |
|
898 elsif (-d $file) |
|
899 { |
|
900 $file = abs_path($file); |
|
901 } # else does not exist, so just convert to unix-style path |
|
902 $file=~tr/\\/\//; |
|
903 return "file:///$file"; |
|
904 } |
|
905 |
|
906 |
|
907 sub RunCmd() { |
|
908 my $command = shift; |
|
909 open(EXE,"$command 2>&1|"); |
|
910 while(<EXE>){ |
|
911 chomp; |
|
912 s/^XSLT Message: //; |
|
913 s/\.Source tree node:.*$//; |
|
914 if($_ ne '') { |
|
915 if(s/^note: //i) { |
|
916 &Logger::LogInfo($_, 100); |
|
917 } elsif(s/^Warning: //) { |
|
918 &Logger::LogInfo($_, 600); |
|
919 } elsif(s/^Error: //i) { |
|
920 &Logger::LogInfo($_, 400); |
|
921 } else { |
|
922 print STDERR "$_\n"; |
|
923 } |
|
924 } |
|
925 } |
|
926 close(EXE); |
|
927 return $?; |
|
928 } |
|
929 |
|
930 sub ShouldCreateDepmodel() |
|
931 { |
|
932 my $self = shift; |
|
933 if ($self->{iDepsFile}) |
|
934 { |
|
935 return 1; |
|
936 } |
|
937 my $model = $self->getModel(); |
|
938 my $t = $/; |
|
939 $/='>'; |
|
940 open(M,$model); |
|
941 while(<M>) |
|
942 { |
|
943 if(/<model\s/){last} |
|
944 } |
|
945 close M; |
|
946 $/ = $t; |
|
947 return /\sdeps=/; |
|
948 } |
|
949 |
|
950 sub XsltTransform() |
|
951 { |
|
952 my $xslt = shift; |
|
953 my $from = shift; |
|
954 my $to = shift; |
|
955 my $indent = shift; |
|
956 my %params = %{$_[0]}; |
|
957 my $xsltParams; |
|
958 |
|
959 # windows-specific stuff follows |
|
960 |
|
961 if(! ($xslt=~/^..+:/)) {$xslt =~ s#\/#\\#g} #it's not a URL |
|
962 if(! ($from=~/^..+:/)) {$from =~ s#\/#\\#g} #it's not a URL |
|
963 if(! ($to=~/^..+:/)) {$to =~ s#\/#\\#g} #it's not a URL |
|
964 |
|
965 while (my($p,$v) = each(%{$_[0]})) |
|
966 { |
|
967 $v =~ s/"/"/g; #" |
|
968 $xsltParams.= " -p $p \"$v\""; |
|
969 } |
|
970 |
|
971 my $command = &DepConstants::Xalan(); |
|
972 $command =~ s#\/#\\#g; |
|
973 $command .= $xsltParams; |
|
974 if($indent >=0) { |
|
975 $command .= " -i $indent"; |
|
976 } |
|
977 if($to ne '') { |
|
978 $command .= " -o \"$to\""; |
|
979 } |
|
980 $command.=" \"$from\" \"$xslt\""; |
|
981 &Logger::LogInfo("System Call: $command", 800); |
|
982 if($to eq '') {return `$command`} |
|
983 return &RunCmd($command); |
|
984 } |
|
985 |
|
986 sub Draw() |
|
987 { |
|
988 my $self = shift; |
|
989 my $genSvg = $self->{'iDiagram'} ne ''; |
|
990 my $genCsv = $self->{'iOutputCsv'} ne ''; |
|
991 my $genXml = $self->{'iOutputXml'} ne ''; |
|
992 |
|
993 if(!$genSvg && !$genCsv && !$genXml) |
|
994 { |
|
995 &Logger::LogFatal("Must specify at least one type of output file. Cannot continue...", $self->{iScriptCode}); |
|
996 } |
|
997 |
|
998 &Logger::LogInfo("Creating sysmodel.svg...", $self->{iScriptCode}); |
|
999 |
|
1000 # Step 0: |
|
1001 # Prepare some file names and create output directory: |
|
1002 |
|
1003 # construct full path name: |
|
1004 ($self->{iRootDirectory} = cwd ) =~ s#\/#\\#g; |
|
1005 chdir($self->{iTemporaryDirectory}); |
|
1006 my $tempDirectoryPathname = cwd; # now gives the full path name $self->{iTemporaryDirectory} |
|
1007 chdir($self->{iRootDirectory}); # change back! |
|
1008 |
|
1009 my $xsltDir = $self->GetXsltDir(); |
|
1010 |
|
1011 my $tempStuctureFile = "$tempDirectoryPathname/system_model_svg_tmp.xml"; |
|
1012 my $tempXslFile = "$tempDirectoryPathname/system_model_svg_tmp.xsl"; |
|
1013 my $tempModelFile = "$tempDirectoryPathname/model_tmp.svg"; |
|
1014 my $tempModelFile2 = "$tempDirectoryPathname/model_tmp2.svg"; |
|
1015 my $modelXsl = $xsltDir."/Model.xsl"; |
|
1016 |
|
1017 |
|
1018 my $modelXml = $self->getModel(); |
|
1019 |
|
1020 # Step 2 |
|
1021 # xalan -i 2 model.xml model.xsl > tmp.xml |
|
1022 $error = &XsltTransform($modelXsl,$modelXml,$tempStuctureFile,1, $self->{'iXsltParam'}); |
|
1023 |
|
1024 &Logger::LogError("Xalan error ($error) occured in Step 2 of SVG building...", $self->{iScriptCode}, 1) if $error; |
|
1025 |
|
1026 # Step 3 - validation |
|
1027 # xalan tmp.xml validate.xsl |
|
1028 if($self->{iWarningLevel} == DepConstants::VERBOSE ) |
|
1029 { |
|
1030 my $errors = &XsltTransform($xsltDir."/validate.xsl",$tempStuctureFile,'',-1); |
|
1031 &Logger::LogList(split(/\n/,$errors)); |
|
1032 } |
|
1033 if($genSvg) |
|
1034 { # only needed for model building |
|
1035 |
|
1036 # Step 4 |
|
1037 # xalan -i 2 model.xml shapes.xsl > tmp.xsl |
|
1038 $error = &XsltTransform("$xsltDir/Shapes.xsl",$modelXml,$tempXslFile,1, |
|
1039 {%{$self->{'iXsltParam'}},'Model-Transform' => "'".&FileAsUrl($modelXsl)."'" }); |
|
1040 &Logger::LogError("Xalan error ($error) occured in Step 4 of SVG building...", $self->{iScriptCode}, 1) if $error; |
|
1041 |
|
1042 # Step 5 |
|
1043 # xalan -i 2 tmp.xml tmp.xsl > tmp.svg |
|
1044 $error = &XsltTransform($tempXslFile,$tempStuctureFile,$tempModelFile,1,$self->{'iXsltParam'}); |
|
1045 &Logger::LogError("Xalan error ($error) occured in Step 4 of SVG building...", $self->{iScriptCode}, 1) if $error; |
|
1046 |
|
1047 if ($self->ShouldCreateDepmodel()) { # insert as 1st transform |
|
1048 @ARGV=( $xsltDir."/Postprocess.xsl",'-',@ARGV) |
|
1049 } |
|
1050 my $tmpsvg = $tempModelFile; |
|
1051 while(scalar(@ARGV)) { |
|
1052 my $transform = shift(@ARGV); |
|
1053 my $datafile = shift(@ARGV); |
|
1054 if($datafile eq '-') {$datafile = &FileAsUrl($tempStuctureFile)} |
|
1055 elsif($datafile ne '') {$datafile = &FileAsUrl($datafile)} |
|
1056 # save to the output if this is the last transform |
|
1057 # otherwise save to tempModelFile2 if reading from tempModelFile, and vis versa |
|
1058 my $saveto = $self->{'iDiagram'}; |
|
1059 if(scalar(ARGV)) { |
|
1060 $saveto = ($tmpsvg eq $tempModelFile) ? $tempModelFile2 : $tempModelFile; |
|
1061 } |
|
1062 # Step 6 |
|
1063 # xalan -i 2 -p Data tmp.xml 'tmp.svg' postprocess.xsl> final.svg |
|
1064 my %p; |
|
1065 if($datafile ne '') { |
|
1066 $p{'Data'}="'$datafile'"; # optional -- only if needed for transform |
|
1067 } |
|
1068 $error = &XsltTransform($transform,$tmpsvg,$saveto,1,\%p); |
|
1069 &Logger::LogError("Xalan error ($error) occured in Step 6 of SVG building...", $self->{iScriptCode}, 1) if $error; |
|
1070 $tmpsvg = $saveto; # read from this next time. |
|
1071 } |
|
1072 if ($tmpsvg ne $self->{'iDiagram'}) { |
|
1073 open(OUT,">".$self->{iDiagram}); |
|
1074 open(IN,$tmpsvg); |
|
1075 print OUT <IN>; |
|
1076 close OUT; |
|
1077 close IN; |
|
1078 } |
|
1079 |
|
1080 my $zipname = $self->{iDiagram}; |
|
1081 my $unzipname = $zipname; |
|
1082 $zipname =~ s/\.svg$/.svgz/i; |
|
1083 $unzipname =~ s/\.svgz$/.svg/i; |
|
1084 my $compressed = 0; |
|
1085 if($self->{iCompress}) |
|
1086 { |
|
1087 my $gzip = &DepConstants::GzipCommand(); |
|
1088 if($gzip) |
|
1089 { |
|
1090 my $command = "$gzip ".$self->{iDiagram}; |
|
1091 &Logger::LogInfo("System Call: $command", $self->{iScriptCode}); |
|
1092 $error = &RunCmd($command);# this should generate the sysmodel.svg in the output directory |
|
1093 &Logger::LogError("Gzip error ($error) occured when comrpessing SVG", $self->{iScriptCode}, 1) if $error; |
|
1094 &Logger::LogInfo("Renaming output to : $zipname", $self->{iScriptCode}); |
|
1095 rename $self->{iDiagram}.".gz", $zipname; |
|
1096 $compressed = 1; |
|
1097 } |
|
1098 } |
|
1099 if(!$compressed && $unzipname ne $self->{iDiagram}) |
|
1100 { |
|
1101 &Logger::LogInfo("Renaming output to : $unzipname", $self->{iScriptCode}); |
|
1102 rename $self->{iDiagram}, $unzipname; |
|
1103 } |
|
1104 } |
|
1105 # create CSV if desired |
|
1106 if($genCsv) |
|
1107 { |
|
1108 my %p; |
|
1109 if($self->{iCsvColumns}) |
|
1110 { |
|
1111 $p{'atts'}="'".$self->{iCsvColumns}."'"; |
|
1112 } |
|
1113 if($self->{iCsvLabels}) |
|
1114 { |
|
1115 $p{'labels'}="'".$self->{iCsvLabels}."'"; |
|
1116 } |
|
1117 $error = &XsltTransform($xsltDir."/output-csv.xsl",$tempStuctureFile,$self->{iOutputCsv},-1,\%p); |
|
1118 &Logger::LogError("Xalan error ($error) occured in CSV output...", $self->{iScriptCode}, 1) if $error; |
|
1119 } |
|
1120 |
|
1121 # create sysdef XML if desired |
|
1122 |
|
1123 if($genXml) |
|
1124 { |
|
1125 $error = &XsltTransform($xsltDir."/output-sysdef.xsl",$tempStuctureFile,$self->{iOutputXml},1); |
|
1126 &Logger::LogError("Xalan error ($error) occured in Sysdef output...", $self->{iScriptCode}, 1) if $error; |
|
1127 } |
|
1128 |
|
1129 # delete the contents of the temp directory if -clean is specified by the user: |
|
1130 if ($self->{iClean}) |
|
1131 { |
|
1132 &Logger::LogInfo("Deleting contents of the temp directory $self->{iTemporaryDirectory}...", 100); |
|
1133 $self->DeleteTempDirectory(); |
|
1134 } |
|
1135 } |
|
1136 |
|
1137 sub CreateSysDefTagsForModelXML() |
|
1138 { |
|
1139 my $self = shift; |
|
1140 my $sysdefXml = shift; |
|
1141 my $srcvar = shift; |
|
1142 |
|
1143 if($sysdefXml eq '') |
|
1144 { |
|
1145 &Logger::LogInfo("Cannot find System Definition file", 100); |
|
1146 return; |
|
1147 } |
|
1148 |
|
1149 my $ret = "<sysdef href=\"".&FileAsUrl($sysdefXml)."\""; |
|
1150 if($srcvar ne '') {$ret.=" root=\"$srcvar\""} |
|
1151 $ret .=">\n" . |
|
1152 $self->MakeMultiInfo('iExtra' => 'extra', 'iLevels' => 'levels' , 'iS12' => 's12'); |
|
1153 return "$ret\t</sysdef>\n"; |
|
1154 } |
|
1155 |
|
1156 sub DeleteTempDirectory() |
|
1157 { |
|
1158 my $self = shift; |
|
1159 # This will delete all files in the $self->{iTemporaryDirectory} |
|
1160 rmtree $self->{iTemporaryDirectory}; |
|
1161 } |
|
1162 |
|
1163 sub Help() |
|
1164 { |
|
1165 my $self = shift; |
|
1166 format STDERR = |
|
1167 @<<<<<<<<<<<<<<<<<<<< ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< |
|
1168 $param, $text, |
|
1169 ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<~~ |
|
1170 $text |
|
1171 . |
|
1172 my @list =( |
|
1173 'Switch', 'Explanation', |
|
1174 '------', '-----------', |
|
1175 '-h' , 'Help on usage', |
|
1176 '-i' , 'An INI file listing one argument per line, with the syntax: <argument> = <value>', |
|
1177 '==== Build Control ====', |
|
1178 '-w' , 'Warning level. 1: errors only (default), 2: warnings as well as errors, 3: info messages, warnings and errors, 4: all plus deep syntax validation and reporting -- note that this can take a long time to compute so do not use this warning level by default', |
|
1179 '-tempdir', 'Temporary directory for build files. Defaults to drawsvg_temp', |
|
1180 '-output', 'The name of the file to save the built System Model SVG. If in the format filename.svgz, it will attempt to compress the file. If compression is not supported, it will rename the output to filename.svg. Defaults to sysmodel.svg or sysmodel.svgz if -compress is set.', |
|
1181 '-csv_output', 'The name of the file to save a CSV description of the built System Model. Only items shown on the system model will be included.', |
|
1182 '-csv_columns', 'Comma-separated list of columns to include in the output CSV. This does nothing if -csv_output is not present. By default (if -csv_columns is not present), the columns will be a sorted list of all attributes on all items. ', |
|
1183 '-csv_labels', 'Comma-separated list of columns labels include in the output CSV. Do not use quotes or commas in label names. This does nothing if -csv_output is not present. If this list is shorter than -csv_columns, the remaining columns will use the attribute name as the label. ', |
|
1184 '-xml_output', 'The name of the file to save a combined system definition XML. Only items shown in the built system model will be included.', |
|
1185 '-log' , 'File in which to store output. Defaults to stdout', |
|
1186 '-compress', 'If set, it will attempt to compress the output as an SVGZ file. In order to success gzip must be installed and in the PATH. This will also rename the output file from filename.svg to filename.svgz.', |
|
1187 '-clean' , 'Caution: if set, it will delete the contents of the temporary directory.', |
|
1188 "==== Files or URIs ====\nAll of these take a file name (relative or absolute path) or URI of a data source", |
|
1189 '-model', 'The location of the Model XML file to use to build the file. If this is provided all other non-build control command line and ini options are ignored.', |
|
1190 '-shapes', 'The location of the Shapes XML file used to provide rules to control the display of the components on the model. If not present, default behaviour (in Shapes.xml) is used. This and the default bahaviours are overrriden by using the -color, -border, -pattern, and -style options. ', |
|
1191 '-localize', 'The location of the Localization file used to provide displayable names for the model entities. By default, the provided "display-names.xml" is used.', |
|
1192 '-s12', 'The location of the Schedule 12 XML file used to provide the border shapres of the components. If this a directory, the S12 XML file is found by appending "Symbian_OS_v[system_version]_Schedule12.xml" to the directory.', |
|
1193 '-levels', 'The location of the Levels XML file used to override the stacking of collections. ', |
|
1194 '-sysinfo', 'The location of extra component information used to provided additional properies for components. By default, the provided "SystemInfo.xml" is used.', |
|
1195 '-deps', 'The location of the Dependencies XML file used to draw the depmodel. If not present, dependencies will not be drawn', |
|
1196 '-color', 'The location of a Values XML file used to specify per-component colours. If not present, the default colours are used.', |
|
1197 '-border-shape', 'The location of a Values XML file used to specify the shape (border) of each component. If not present, the default borders are used.', |
|
1198 '-pattern', 'The location of a Values XML file used to specify per-component overlay patterns. If not present, the default patterns (for new and reference components) are used.', |
|
1199 '-border-style', 'The location of a Values XML file used to specify per-component border styles. If not present, the default border styles are used. ', |
|
1200 '-link','The base URL to use for all hyperlinks in the model. A base URL will be appended by the type and name (e.g. Blocks/Comms%20Services.html) of the items to create the full URL of the linked file. Window directories will be converted into file URIs.', |
|
1201 "==== Labels ====\nAll of these take a plain text value which is displayed on the model", |
|
1202 '-system_name', 'The name of the product described in the model. It appears at the bottom right. Defaults to "Symbian OS"', |
|
1203 '-system_version', 'The version of the product described in the model. It appears at the bottom right after the name.', |
|
1204 '-model_name', 'The label for the model. It appears at the bottom right, under the name. Defaults to "System Model".', |
|
1205 '-model_version', 'A number which appears before th model-revision-type. If specified this overrides the build number used by depmodel. If not building depmodel, this defaults to "1"', |
|
1206 '-model_version_type', 'One of "draft", "issued", "build" or free-text value. Appears below the model label. If specified this overrides the build number used by DepToolkit.If not building depmodel, this defaults to "draft"', |
|
1207 '-copyright', 'The copyright to appear in the lower left. Set to empty string to leave out. Defaults to "[this year] Nokia Corporation"', |
|
1208 '-distribution', 'Text to appear on the bottom centre to indicate to whom the model can be show. Informational only. Suggested values are "internal", "secret" or "unrestrictred". Not shown if not set.', |
|
1209 '-note', 'Free text to appear inside the legend box, on the rightmost side. If multiple ones are provided, they will appear as separate boxes from left to right. Newlines and otehr special characters can be entity-encoded (e.g. 
)', |
|
1210 "==== Model Control ====", |
|
1211 '-sysdef [uri-list]', 'Comma-separated list of locations for the System Definition XML file(s) used to build the model. Layers in the files will be stacked on top of each other in order, from bottom to top.', |
|
1212 '-coreos [on/off/new]', 'Turn on or off Core OS colouring, or use the new colouring for 9.5 and later models. Defaults to "off" for model versions before 9.4 or those with no specified version, "on" for 9.4 and "new" for 9.5 and later', |
|
1213 '-filter [filter-name]', 'The name of a filter to turn on when building the model. All filters on an item must be present in this list in order for that item to appear. Can have any number of these Defaults to "java" and "gt"', |
|
1214 '-filter-has [filter-name]', 'Like -filter, except any filter on an item must be present in this list in order for that item to appear. Include "*" in the list in order to show items with no filters. Equivalent to "-show-attr filter xxx"', |
|
1215 '-ignore [item]', 'A model entity to not draw, in the form "[item-type]:[item-name]". Any number of these can be used. Defaults to "layer:Tools and Utils and SDKENG" ,"layer:MISC", "block:Techview"', |
|
1216 '-show-attr [attr[=val]]', 'A mechanism of filtering which allows filtering based on component attribute values. If a value is set for that attribute, the component will be shown. Use in conjunction with -hide-attr for fine contol of what is shown. "class" and "filter" attribtues are handled specially -- see the documentation for details', |
|
1217 '-hide-attr [attr[=val]]', 'A mechanism of filtering which allows filtering based on component attribute values. If a value is set for that attribute, the component will not be shown on the model. Use in conjunction with -show-attr for fine contol of what is shown. "class" and "filter" attribtues are handled specially -- see the documentation for details', |
|
1218 '-detail [item-type]' , 'The type of the smallest System Model entity to draw. One of "layer", "block", "subblock", "collection" or "component". Defaults to "component"', |
|
1219 '-detail-type [type]' , 'If set to "fixed", the smallest System Model entity drawn will have a fixed width (rather then sized by their invisible components). This can be used to reduce the size and complexity of the overall model.', |
|
1220 '-page-width [length]', 'The width of the drawn image (with units). If not specified it will fit the viewer window. Valid units: "in", "mm", "cm", "px", "pt"', |
|
1221 '-static', 'If present, the model will not have any mouseover effects (this is overriden by builing the depmodel).', |
|
1222 '-logo [file]', 'If present, the logo will be drawn in the lower-left corner of the model. If the logo is an SVG file, -logo-width and -logo-height are optional, otherwise the must both be specified', |
|
1223 '-logo-height [length]', 'Specifies the height of the logo (if any) in mm. Width is scaled along with height unless otherwise specified. Both width and height MUST be specified if a bitmap image is used', |
|
1224 '-logo-width [length]', 'Specifies the width of the logo (if any) in mm. Height is scaled along with width unless otherwise specified. Both width and height MUST be specified if a bitmap image is used', |
|
1225 '-legend-width [%]', 'The percent width of the model the legend takes up. This will scale the size of the legend and model title, but not the logo, to fill the specified space. If a logo is included, but no width specified, the legend cannot be scaled since it will not be able to determine the available space. Note that that -max-legend-scale will further limit the potential width.', |
|
1226 '-legend-max-scale [scale]', 'Specifies the maximum scale factor for resizing the legend. If this is present and -legend-width is not, the legend and title will scale to 100% of the available width. If both are present the scale factor will take precedent. If neither is present, the legend will not resize. Note that when this is used, the legend can shrink if it would normally be wider than the model.', |
|
1227 '-title-scale [scale]', 'Specifies the scale factor for the size of the title font (the text in the lower right). Use this instead of CSS to control the size, since the model generator needs to explicitly know how much space to allocate for the title.', |
|
1228 '-model_font [font]', 'The name of the base font to use to draw the model. This will be overriden by any custom CSS in the Shapes XML', |
|
1229 '-dpi [number]', 'The DPI to use when printing from the Adobe SVG Viewer. If not present, it will print well at A4 size. A value of 300 will look good on A3 size paper' |
|
1230 ); |
|
1231 print STDERR "Usage: DrawSvg.pl [Arguments] [Transform Data-file] ...\n\nArguments:\n"; |
|
1232 my $head=2; |
|
1233 while(@list) { |
|
1234 $param = shift(@list); |
|
1235 if($head<=0 and !($param=~/^-/)){print "\n$param\n";next;} |
|
1236 $text = shift(@list); |
|
1237 write STDERR ; |
|
1238 $head--; |
|
1239 } |
|
1240 return; |
|
1241 } |
|
1242 |
|
1243 1; |
|