|
1 # Copyright (c) 2000-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 the License "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 # |
|
15 # |
|
16 |
|
17 package IniData; |
|
18 |
|
19 use strict; |
|
20 use FindBin; |
|
21 use File::Path; |
|
22 use File::Spec; |
|
23 use Utils; |
|
24 use PathData; |
|
25 |
|
26 our $cache = {}; # Persistent (private) cache |
|
27 |
|
28 $|++; |
|
29 |
|
30 # |
|
31 # Constants. |
|
32 # |
|
33 |
|
34 my $iniName = \ 'reltools.ini'; |
|
35 my $envDir = undef; # only filled in when we do New() |
|
36 my $binDir = \ "$FindBin::Bin\\"; |
|
37 my @standardIgnores = ('\\epoc32\\build\\*', |
|
38 '\\epoc32\\wins\\c\\*', |
|
39 '\\epoc32\\winscw\\c\\*', |
|
40 '\\epoc32\\release\\*.ilk', |
|
41 '\\epoc32\\release\\*.bsc', |
|
42 '\\epoc32\\data\\emulator\\*.sys.ini', |
|
43 '\\epoc32\\release\\tools\\*', |
|
44 '\\epoc32\\release\\tools2\\*' |
|
45 ); |
|
46 |
|
47 # Support for target alias file |
|
48 use constant CBR_TARGET_ALIAS_LOCATION => scalar "\\epoc32\\tools\\variant\\"; |
|
49 |
|
50 # |
|
51 # Constructor |
|
52 # |
|
53 |
|
54 sub New { |
|
55 my $pkg = shift; |
|
56 my $filename = shift; |
|
57 my $ignoreepocroot = shift; |
|
58 |
|
59 if ( defined ($ENV{EPOCROOT}) or ! $ignoreepocroot ){ |
|
60 $envDir = \ Utils::PrependEpocRoot("\\epoc32\\relinfo\\"); |
|
61 } |
|
62 |
|
63 my $self = {}; |
|
64 |
|
65 $self->{warnIniLocation} = 0; |
|
66 # Support for target alias file |
|
67 # This is a persistant flag. |
|
68 # If set then a warning must be printed if either HasTargetPlatforms() |
|
69 # or TargetPlatforms() is used. The flag is then cleared thus the warning is a one off. |
|
70 # If clear this is because the cbrtargetsalias.cfg file has been found |
|
71 # or the no_target_alias_warning flag is set in reltools.ini |
|
72 $self->{mustWarnTargetAliasLocation} = 1; |
|
73 if (defined $filename and -e $filename ) { |
|
74 $self->{iniFileName} = $filename; |
|
75 } elsif (defined $$envDir and -e "$$envDir$$iniName" ) { |
|
76 $self->{iniFileName} = "$$envDir$$iniName"; |
|
77 } elsif (-e "$$binDir$$iniName") { |
|
78 $self->{warnIniLocation} = 1; |
|
79 $self->{iniFileName} = "$$binDir$$iniName"; |
|
80 } else { |
|
81 my $msg = "Error: \"$$iniName\" not found in "; |
|
82 $msg = $msg."either \"$$envDir\" or " if ( defined ($$envDir)); |
|
83 $msg = $msg."\"$$binDir\"\n"; |
|
84 die $msg; |
|
85 } |
|
86 |
|
87 if ($cache->{lc($self->{iniFileName})}) { |
|
88 return $cache->{lc($self->{iniFileName})}; |
|
89 } |
|
90 |
|
91 foreach my $thisIgnore (@standardIgnores) { |
|
92 push (@{$self->{binIgnore}}, $thisIgnore); |
|
93 } |
|
94 |
|
95 bless $self, $pkg; # $self isn't blessed until we know we need it |
|
96 |
|
97 $self->ReadIni(); |
|
98 |
|
99 # Support for target alias file |
|
100 if (!$ignoreepocroot) { |
|
101 $self->{targetAliasName} = Utils::PrependEpocRoot(CBR_TARGET_ALIAS_LOCATION).'cbrtargetalias.cfg'; |
|
102 |
|
103 if ($self->ReadTargetAliasFile == 1) { |
|
104 # Successful read so clear the warning flag |
|
105 $self->{mustWarnTargetAliasLocation} = 0; |
|
106 } |
|
107 } |
|
108 |
|
109 $cache->{lc($self->{iniFileName})} = $self; |
|
110 |
|
111 return $self; |
|
112 } |
|
113 |
|
114 # |
|
115 # Public |
|
116 # |
|
117 |
|
118 sub DiffTool { |
|
119 my $self = shift; |
|
120 unless (exists $self->{diff_tool}) { |
|
121 return undef; |
|
122 } |
|
123 return $self->{diff_tool}; |
|
124 } |
|
125 |
|
126 sub RequireInternalVersions { |
|
127 my $self = shift; |
|
128 if (exists $self->{require_internal_versions}) { |
|
129 return 1; |
|
130 } |
|
131 return 0; |
|
132 } |
|
133 |
|
134 sub IgnoreSourceFilterErrors { |
|
135 my $self = shift; |
|
136 if (exists $self->{ignore_source_filter_errors}) { |
|
137 return 1; |
|
138 } |
|
139 return 0; |
|
140 } |
|
141 |
|
142 sub RemoteSiteType { |
|
143 my $self = shift; |
|
144 |
|
145 unless (exists $self->{remote_site_type}) { |
|
146 $self->{remote_site_type} = 'FTP'; |
|
147 } |
|
148 elsif ($self->{remote_site_type} =~ /(network|drive)/i) { |
|
149 $self->{remote_site_type} = 'NetDrive'; |
|
150 } |
|
151 elsif ($self->{remote_site_type} =~ /experimentalproxy/i) { |
|
152 $self->{remote_site_type} = 'FTP::Proxy::Experimental'; |
|
153 } |
|
154 elsif ($self->{remote_site_type} =~ /experimentalftp/i) { |
|
155 $self->{remote_site_type} = 'FTP::Experimental'; |
|
156 } |
|
157 elsif ($self->{remote_site_type} =~ /multivolumeexport/i) { |
|
158 $self->{remote_site_type} = 'NetDrive::MultiVolumeExport'; |
|
159 } |
|
160 elsif ($self->{remote_site_type} =~ /multivolumeimport/i) { |
|
161 $self->{remote_site_type} = 'NetDrive::MultiVolumeImport'; |
|
162 } |
|
163 elsif ($self->{remote_site_type} =~ /proxy/i) { |
|
164 $self->{remote_site_type} = 'FTP::Proxy'; |
|
165 } |
|
166 else { |
|
167 $self->{remote_site_type} = 'FTP'; |
|
168 } |
|
169 return $self->{remote_site_type}; |
|
170 } |
|
171 |
|
172 sub RemoteHost { |
|
173 my $self = shift; |
|
174 unless (exists $self->{remote_host}) { |
|
175 return undef; |
|
176 } |
|
177 return $self->{remote_host}; |
|
178 } |
|
179 |
|
180 sub RemoteUsername { |
|
181 my $self = shift; |
|
182 unless (exists $self->{remote_username}) { |
|
183 return undef; |
|
184 } |
|
185 return $self->{remote_username}; |
|
186 } |
|
187 |
|
188 sub RemotePassword { |
|
189 my $self = shift; |
|
190 unless (exists $self->{remote_password}) { |
|
191 return undef; |
|
192 } |
|
193 return $self->{remote_password}; |
|
194 } |
|
195 |
|
196 sub RemoteLogsDir { |
|
197 my $self = shift; |
|
198 unless (exists $self->{remote_logs}) { |
|
199 return undef; |
|
200 } |
|
201 return $self->{remote_logs}; |
|
202 } |
|
203 |
|
204 sub Proxy { |
|
205 my $self = shift; |
|
206 unless (exists $self->{proxy}) { |
|
207 return undef; |
|
208 } |
|
209 return $self->{proxy}; |
|
210 } |
|
211 |
|
212 sub ProxyUsername { |
|
213 my $self = shift; |
|
214 unless (exists $self->{proxy_username}) { |
|
215 return undef; |
|
216 } |
|
217 return $self->{proxy_username}; |
|
218 } |
|
219 |
|
220 sub ProxyPassword { |
|
221 my $self = shift; |
|
222 unless (exists $self->{proxy_password}) { |
|
223 return undef; |
|
224 } |
|
225 return $self->{proxy_password}; |
|
226 } |
|
227 |
|
228 sub PasvTransferMode { |
|
229 my $self = shift; |
|
230 if (exists $self->{pasv_transfer_mode}) { |
|
231 return 1; |
|
232 } |
|
233 return 0; |
|
234 } |
|
235 |
|
236 sub FtpServerSupportsResume { |
|
237 my $self = shift; |
|
238 if (defined $_[0]) { |
|
239 $self->{ftp_server_supports_resume} = $_[0]; |
|
240 } |
|
241 if (exists $self->{ftp_server_supports_resume}) { |
|
242 return $self->{ftp_server_supports_resume} ? 1 : 0; |
|
243 } |
|
244 return 0; |
|
245 } |
|
246 |
|
247 sub FtpTimeout { |
|
248 my $self = shift; |
|
249 unless (exists $self->{ftp_timeout}) { |
|
250 return undef; |
|
251 } |
|
252 return $self->{ftp_timeout}; |
|
253 } |
|
254 |
|
255 sub FtpReconnectAttempts { |
|
256 my $self = shift; |
|
257 unless (exists $self->{ftp_reconnect_attempts}) { |
|
258 return undef; |
|
259 } |
|
260 return $self->{ftp_reconnect_attempts}; |
|
261 } |
|
262 |
|
263 sub TempDir { |
|
264 my $self = shift; |
|
265 if (exists $self->{temp_dir}) { |
|
266 return $self->{temp_dir}; |
|
267 } |
|
268 return undef; |
|
269 } |
|
270 |
|
271 sub MaxExportVolumeSize { |
|
272 my $self = shift; |
|
273 if (exists $self->{max_export_volume_size}) { |
|
274 return $self->{max_export_volume_size}; |
|
275 } |
|
276 else { |
|
277 return 639 * 1024 * 1024; |
|
278 } |
|
279 } |
|
280 |
|
281 sub PgpTool { |
|
282 my $self = shift; |
|
283 |
|
284 unless (exists $self->{pgp_tool}) { |
|
285 $self->{pgp_tool} = 'PGP'; |
|
286 } |
|
287 elsif ($self->{pgp_tool} =~ /(gpg|gnupg)/i) { |
|
288 $self->{pgp_tool} = 'GPG'; |
|
289 } |
|
290 else { |
|
291 $self->{pgp_tool} = 'PGP'; |
|
292 } |
|
293 return $self->{pgp_tool}; |
|
294 } |
|
295 |
|
296 sub PgpEncryptionKeys { |
|
297 my $self = shift; |
|
298 unless (exists $self->{pgp_encryption_keys}) { |
|
299 return []; |
|
300 } |
|
301 return $self->{pgp_encryption_keys}; |
|
302 } |
|
303 |
|
304 sub PgpConfigPath { |
|
305 my $self = shift; |
|
306 unless (exists $self->{pgp_config_path}) { |
|
307 return undef; |
|
308 } |
|
309 return $self->{pgp_config_path}; |
|
310 } |
|
311 |
|
312 sub ExportDataFile { |
|
313 my $self = shift; |
|
314 unless (exists $self->{export_data_file}) { |
|
315 die "Error: export_data_file keyword not specified in reltools.ini\n"; |
|
316 } |
|
317 return $self->{export_data_file}; |
|
318 } |
|
319 |
|
320 sub PathData { |
|
321 my $self = shift; |
|
322 unless (defined $self->{pathData}) { |
|
323 $self->{pathData} = PathData->New($self->{verbose}); |
|
324 } |
|
325 return $self->{pathData}; |
|
326 } |
|
327 |
|
328 sub HtmlNotes { |
|
329 my $self = shift; |
|
330 return (exists $self->{html_notes}); |
|
331 } |
|
332 |
|
333 sub FromMapping { |
|
334 my $self = shift; |
|
335 my @fromMapping; |
|
336 |
|
337 if(defined @{$self->{from_mapping}}){ |
|
338 @fromMapping = @{$self->{from_mapping}}; |
|
339 } |
|
340 |
|
341 return @fromMapping; |
|
342 } |
|
343 |
|
344 sub ToMapping { |
|
345 my $self = shift; |
|
346 my @toMapping; |
|
347 |
|
348 if(defined @{$self->{to_mapping}}){ |
|
349 @toMapping = @{$self->{to_mapping}}; |
|
350 } |
|
351 |
|
352 return @toMapping; |
|
353 } |
|
354 |
|
355 sub HasMappings { |
|
356 my $self = shift; |
|
357 my $result = 0; |
|
358 |
|
359 if(defined @{$self->{from_mapping}} && defined @{$self->{to_mapping}} && Utils::SourceRoot() eq "\\"){ |
|
360 $result = 1; |
|
361 } |
|
362 |
|
363 return $result; |
|
364 } |
|
365 |
|
366 sub PerformMapOnFileName { |
|
367 my $self = shift; |
|
368 my $operand = shift; |
|
369 |
|
370 my @fromMapping = $self->FromMapping(); |
|
371 my @toMapping = $self->ToMapping(); |
|
372 my $fromMappingSize = @fromMapping; |
|
373 |
|
374 unless($operand =~ /^\\.*/) { |
|
375 $operand = "\\"."$operand"; # Add a \\ to the beginning, which is equal to srcroot. |
|
376 } |
|
377 |
|
378 if(@fromMapping) { |
|
379 for(my $position = 0; $position<$fromMappingSize; $position++) { |
|
380 if($operand =~ /^\Q$fromMapping[$position]\E/i){ |
|
381 $operand =~ s/^\Q$fromMapping[$position]\E/$toMapping[$position]/i; |
|
382 last; |
|
383 } |
|
384 } |
|
385 } |
|
386 |
|
387 return $operand; |
|
388 } |
|
389 |
|
390 sub PerformReverseMapOnFileName { |
|
391 my $self = shift; |
|
392 my $operand = shift; |
|
393 |
|
394 my @fromMapping = $self->FromMapping(); |
|
395 my @toMapping = $self->ToMapping(); |
|
396 my $toMappingSize = @toMapping; |
|
397 |
|
398 unless($operand =~ /^\\(.*)/) { |
|
399 $operand = "\\"."$operand"; # Add a \\ to the beginning, which is equal to srcroot. |
|
400 } |
|
401 |
|
402 if(@toMapping) { |
|
403 for(my $position = 0; $position<$toMappingSize; $position++) { |
|
404 if($operand =~ /^\Q$toMapping[$position]\E/i){ |
|
405 $operand =~ s/^\Q$toMapping[$position]\E/$fromMapping[$position]/i; |
|
406 last; |
|
407 } |
|
408 } |
|
409 } |
|
410 |
|
411 return $operand; |
|
412 } |
|
413 |
|
414 sub CheckFileNameForMappingClash { |
|
415 my $self = shift; |
|
416 my $fileName = shift; |
|
417 |
|
418 my @toMapping = $self->ToMapping(); |
|
419 my $dirName; |
|
420 |
|
421 if($fileName =~ /^(.*)\\/) { |
|
422 $dirName = $1; |
|
423 } |
|
424 |
|
425 if(@toMapping) { |
|
426 foreach my $toMap (@toMapping) { |
|
427 if($dirName =~ /^\Q$toMap\E/i) { |
|
428 die "ERROR: Clash in mappings. The local mapping $toMap clashes with the source directory $dirName.\n"; |
|
429 } |
|
430 } |
|
431 } |
|
432 } |
|
433 |
|
434 sub RemoteSite { |
|
435 my $self = shift; |
|
436 my $verbose = shift; |
|
437 unless (defined $self->{remoteSite}) { |
|
438 my $module = 'RemoteSite::'.$self->RemoteSiteType(); |
|
439 eval "require $module"; |
|
440 $self->{remoteSite} = $module->New(host => $self->RemoteHost(), |
|
441 username => $self->RemoteUsername(), |
|
442 password => $self->RemotePassword(), |
|
443 passive_mode => $self->PasvTransferMode(), |
|
444 resume_mode => $self->FtpServerSupportsResume(), |
|
445 proxy => $self->Proxy(), |
|
446 proxy_username => $self->ProxyUsername(), |
|
447 proxy_password => $self->ProxyPassword(), |
|
448 max_export_volume_size => $self->MaxExportVolumeSize(), |
|
449 verbose => $verbose); |
|
450 die "Failed to create remote site object" unless ref $self->{remoteSite}; |
|
451 } |
|
452 return $self->{remoteSite}; |
|
453 } |
|
454 |
|
455 sub LocalArchivePath { |
|
456 require Carp; |
|
457 Carp->import; |
|
458 confess ("Obsolete method called"); |
|
459 } |
|
460 |
|
461 sub RemoteArchivePath { |
|
462 require Carp; |
|
463 Carp->import; |
|
464 confess ("Obsolete method called"); |
|
465 } |
|
466 |
|
467 sub ArchivePathFile { |
|
468 require Carp; |
|
469 Carp->import; |
|
470 confess ("Obsolete method called"); |
|
471 } |
|
472 |
|
473 sub ListArchiveComponents { |
|
474 require Carp; |
|
475 Carp->import; |
|
476 confess ("Obsolete method called"); |
|
477 } |
|
478 |
|
479 sub BinariesToIgnore { |
|
480 my $self = shift; |
|
481 if (exists $self->{binIgnore}) { |
|
482 return $self->{binIgnore}; |
|
483 } |
|
484 return []; |
|
485 } |
|
486 |
|
487 sub DisallowUnclassifiedSource { |
|
488 my $self = shift; |
|
489 if (exists $self->{disallow_unclassified_source}) { |
|
490 return 1; |
|
491 } |
|
492 return 0; |
|
493 } |
|
494 |
|
495 sub Win32ExtensionsDisabled { |
|
496 my $self = shift; |
|
497 |
|
498 if (exists $self->{disable_win32_extensions}) { |
|
499 return 1; |
|
500 } |
|
501 return 0; |
|
502 } |
|
503 |
|
504 sub CategoriseBinaries { |
|
505 my $self = shift; |
|
506 if (exists $self->{categorise_binaries}) { |
|
507 return 1; |
|
508 } |
|
509 return 0; |
|
510 } |
|
511 |
|
512 sub CategoriseExports { |
|
513 my $self = shift; |
|
514 if (exists $self->{categorise_exports}) { |
|
515 return 1; |
|
516 } |
|
517 return 0; |
|
518 } |
|
519 |
|
520 sub RequiredBinaries { |
|
521 my $self = shift; |
|
522 my $component = lc(shift); |
|
523 if (exists $self->{required_binaries}->{$component}) { |
|
524 return $self->{required_binaries}->{$component}; |
|
525 } |
|
526 elsif (exists $self->{required_binaries}->{default}) { |
|
527 return $self->{required_binaries}->{default}; |
|
528 } |
|
529 return undef; |
|
530 } |
|
531 |
|
532 sub TableFormatter { |
|
533 my $self = shift; |
|
534 require TableFormatter; |
|
535 require POSIX; |
|
536 # Not 'use' because not many commands draw tables so that would be a waste |
|
537 |
|
538 if (!POSIX::isatty('STDOUT')) { |
|
539 $self->{table_format} = "text"; |
|
540 $self->{table_format_args} = ""; |
|
541 } |
|
542 |
|
543 unless (defined $self->{table_formatter}) { |
|
544 my $format = $self->{table_format} || "text"; |
|
545 $self->{table_formatter} = TableFormatter::CreateFormatter($format, $self, $self->{table_format_args}); |
|
546 } |
|
547 |
|
548 return $self->{table_formatter}; |
|
549 } |
|
550 |
|
551 sub LatestVerFilter { |
|
552 my $self = shift; |
|
553 unless (exists $self->{latestver_filter}) { |
|
554 return undef; |
|
555 } |
|
556 return $self->{latestver_filter}; |
|
557 } |
|
558 |
|
559 sub IllegalWorkspaceVolumes { |
|
560 my $self = shift; |
|
561 if (defined $self->{illegal_workspace_volumes}) { |
|
562 return @{$self->{illegal_workspace_volumes}}; |
|
563 } |
|
564 return (); |
|
565 } |
|
566 |
|
567 # |
|
568 # Private |
|
569 # |
|
570 |
|
571 sub CheckMappingPath { |
|
572 my $self = shift; |
|
573 my $operand = shift; |
|
574 |
|
575 # Is used to clean up the mapping path. |
|
576 |
|
577 $operand =~ s/\//\\/g; |
|
578 |
|
579 die "Error: The source_map path $operand must not include a drive letter.\n" if ($operand =~ /^.:/); |
|
580 die "Error: The source_map path $operand must be an absolute path without a drive letter.\n" if ($operand !~ /^\\/); |
|
581 die "Error: The source_map path $operand must not be a UNC path.\n" if ($operand =~ /^\\\\/); |
|
582 |
|
583 #Remove any \\ at the end of the path. |
|
584 if($operand =~ /(.*)\\$/){ |
|
585 $operand = $1; |
|
586 } |
|
587 |
|
588 return $operand; |
|
589 } |
|
590 |
|
591 sub BuildSystemVersion { |
|
592 my $self = shift; |
|
593 my $verbose = shift; |
|
594 |
|
595 if (exists $self->{sbs_version}) { |
|
596 print "User set the value of sbs_version to $self->{sbs_version}\n" if($verbose); |
|
597 return $self->{sbs_version}; |
|
598 } |
|
599 return "0"; |
|
600 } |
|
601 |
|
602 sub ExtractMapping { |
|
603 my $self = shift; |
|
604 my $operand = shift; |
|
605 my $epoc32dir = Utils::EpocRoot()."epoc32"; |
|
606 |
|
607 $operand =~ s/\s+$//; |
|
608 |
|
609 if ($operand =~ /^(\S+)\s+(\S+)$/) { |
|
610 my $archivePath = $self->CheckMappingPath($1); |
|
611 my $localPath = $self->CheckMappingPath($2); |
|
612 |
|
613 if($archivePath =~ /^\Q$epoc32dir\E/i){ |
|
614 die "ERROR: Archive path $epoc32dir... in source mapping is not allowed.\n"; |
|
615 } |
|
616 elsif($localPath =~ /^\Q$epoc32dir\E/i){ |
|
617 die "ERROR: Local path $epoc32dir... in source mapping is not allowed.\n"; |
|
618 } |
|
619 |
|
620 # Need to check whether the from location is already present in from_mapping array |
|
621 if(defined @{$self->{from_mapping}}){ |
|
622 foreach my $fromMap (@{$self->{from_mapping}}) { |
|
623 if(($archivePath =~ /^\W*\Q$fromMap\E\W*$/i) || ($fromMap =~ /^\W*\Q$archivePath\E\W*$/i)){ |
|
624 die "ERROR: Duplicate <archive_source_directory> $fromMap, <archive_source_directory> $archivePath found in source mappings.\n"; |
|
625 } |
|
626 } |
|
627 } |
|
628 |
|
629 # Need to check whether the to location is already present in to_mapping array |
|
630 if(defined @{$self->{to_mapping}}){ |
|
631 foreach my $toMap (@{$self->{to_mapping}}) { |
|
632 if(($localPath =~ /^\W*\Q$toMap\E\W*$/i) || ($toMap =~ /^\W*\Q$localPath\E\W*$/i)){ |
|
633 die "ERROR: Duplicate <local_source_directory> $toMap, <local_source_directory> $localPath found in source mappings.\n"; |
|
634 } |
|
635 } |
|
636 } |
|
637 |
|
638 push @{$self->{from_mapping}}, $archivePath; |
|
639 push @{$self->{to_mapping}}, $localPath; |
|
640 } |
|
641 else{ |
|
642 die "ERROR: Incorrect usage of source_map keyword in reltools.ini. Expected input is source_map <archive_source_directory> <local_source_directory>\n"; |
|
643 } |
|
644 } |
|
645 |
|
646 sub ReadIni { |
|
647 my $self = shift; |
|
648 |
|
649 open (INI, $self->{iniFileName}) or die "Unable to open \"$self->{iniFileName}\" for reading: $!\n"; |
|
650 |
|
651 while (local $_ = <INI>) { |
|
652 # Remove line feed, white space and comments. |
|
653 chomp; |
|
654 s/^\s*$//; |
|
655 |
|
656 # INC105677 - Warn user if remote_password contains an unescaped # |
|
657 if (/remote_password\s+\S*[^\\\s]\#/) { |
|
658 warn "Warning: remote_password appears to contain a comment (# characters need to be escaped)\n"; |
|
659 } |
|
660 |
|
661 s/(?<!\\)#.*//; # remove comments unless they are immediately preceded by \ (negative lookbehind assertion) |
|
662 s/\\#/#/g; # now remove backslashes before # signs |
|
663 |
|
664 if ($_ eq '') { |
|
665 # Nothing left. |
|
666 next; |
|
667 } |
|
668 |
|
669 my $keyWord; |
|
670 my $operand; |
|
671 if (/^(\w+)\s+(.*)/) { |
|
672 $keyWord = $1; |
|
673 $operand = $2; |
|
674 } |
|
675 else { |
|
676 # Must be a line with no operand. |
|
677 $keyWord = $_; |
|
678 } |
|
679 |
|
680 unless (defined $keyWord) { |
|
681 die "Error: Invalid line in \"$self->{iniFileName}\":\n\t$_\n"; |
|
682 next; |
|
683 } |
|
684 |
|
685 if ($keyWord =~ /^diff_tool$/i) { |
|
686 Utils::StripWhiteSpace(\$operand); |
|
687 $self->{diff_tool} = $operand; |
|
688 } |
|
689 elsif ($keyWord =~ /^require_internal_versions$/) { |
|
690 $self->{require_internal_versions} = 1; |
|
691 } |
|
692 elsif ($keyWord =~ /^ignore_source_filter_errors$/) { |
|
693 $self->{ignore_source_filter_errors} = 1; |
|
694 } |
|
695 elsif ($keyWord =~ /^html_notes$/) { |
|
696 $self->{html_notes} = 1; |
|
697 } |
|
698 elsif ($keyWord =~ /^temp_dir$/) { |
|
699 Utils::StripWhiteSpace(\$operand); |
|
700 $operand = File::Spec->catdir($operand); |
|
701 $operand =~ s/[\\\/]$//; |
|
702 if (!-d $operand && length $operand) { |
|
703 die "Error: Invalid line in \"$self->{iniFileName}\":\n\t$_\n$operand does not exist or is an invalid directory name\n"; |
|
704 } |
|
705 $self->{temp_dir} = $operand; |
|
706 } |
|
707 elsif ($keyWord =~ /^remote_site_type$/) { |
|
708 Utils::StripWhiteSpace(\$operand); |
|
709 $self->{remote_site_type} = $operand; |
|
710 } |
|
711 elsif ($keyWord =~ /^remote_host$/) { |
|
712 Utils::StripWhiteSpace(\$operand); |
|
713 $self->{remote_host} = $operand; |
|
714 } |
|
715 elsif ($keyWord =~ /^remote_username$/) { |
|
716 Utils::StripWhiteSpace(\$operand); |
|
717 $self->{remote_username} = $operand; |
|
718 } |
|
719 elsif ($keyWord =~ /^remote_password$/) { |
|
720 Utils::StripWhiteSpace(\$operand); |
|
721 $self->{remote_password} = $operand; |
|
722 } |
|
723 elsif ($keyWord =~ /^remote_logs_dir$/) { |
|
724 Utils::StripWhiteSpace(\$operand); |
|
725 $self->{remote_logs} = $operand; |
|
726 } |
|
727 elsif ($keyWord =~ /^pgp_tool$/) { |
|
728 Utils::StripWhiteSpace(\$operand); |
|
729 $self->{pgp_tool} = $operand; |
|
730 } |
|
731 elsif ($keyWord =~ /^pgp_encryption_key$/) { |
|
732 Utils::StripWhiteSpace(\$operand); |
|
733 push @{$self->{pgp_encryption_keys}}, $operand; |
|
734 } |
|
735 elsif ($keyWord =~ /^pgp_config_path$/) { |
|
736 Utils::StripWhiteSpace(\$operand); |
|
737 $self->{pgp_config_path} = $operand; |
|
738 } |
|
739 elsif ($keyWord =~ /^export_data_file$/) { |
|
740 Utils::StripWhiteSpace(\$operand); |
|
741 $self->{export_data_file} = $operand; |
|
742 } |
|
743 elsif ($keyWord =~ /^archive_path_file$/) { |
|
744 $self->PathData->ProcessLine(\$keyWord, \$operand); |
|
745 } |
|
746 elsif ($keyWord =~ /^archive_path$/) { |
|
747 $self->PathData->ProcessLine(\$keyWord, \$operand); |
|
748 } |
|
749 elsif ($keyWord =~ /^source_map$/) { |
|
750 $self->ExtractMapping($operand); |
|
751 } |
|
752 elsif ($keyWord =~ /^no_ini_location_warning$/) { |
|
753 $self->{warnIniLocation} = 0; |
|
754 } |
|
755 elsif ($keyWord =~ /^ignore_binary$/) { |
|
756 Utils::StripWhiteSpace(\$operand); |
|
757 push (@{$self->{binIgnore}}, $operand); |
|
758 } |
|
759 elsif ($keyWord =~ /^proxy$/) { |
|
760 Utils::StripWhiteSpace(\$operand); |
|
761 $self->{proxy} = $operand; |
|
762 } |
|
763 elsif ($keyWord =~ /^proxy_username$/) { |
|
764 Utils::StripWhiteSpace(\$operand); |
|
765 $self->{proxy_username} = $operand; |
|
766 } |
|
767 elsif ($keyWord =~ /^proxy_password$/) { |
|
768 Utils::StripWhiteSpace(\$operand); |
|
769 $self->{proxy_password} = $operand; |
|
770 } |
|
771 elsif ($keyWord =~ /^pasv_transfer_mode$/) { |
|
772 $self->{pasv_transfer_mode} = 1; |
|
773 } |
|
774 elsif ($keyWord =~ /^ftp_server_supports_resume$/) { |
|
775 $self->{ftp_server_supports_resume} = 1; |
|
776 } |
|
777 elsif ($keyWord =~ /^ftp_timeout$/) { |
|
778 Utils::StripWhiteSpace(\$operand); |
|
779 $self->{ftp_timeout} = $operand; |
|
780 } |
|
781 elsif ($keyWord =~ /^ftp_reconnect_attempts$/) { |
|
782 Utils::StripWhiteSpace(\$operand); |
|
783 $self->{ftp_reconnect_attempts} = $operand; |
|
784 } |
|
785 elsif ($keyWord =~ /^max_export_volume_size$/) { |
|
786 Utils::StripWhiteSpace(\$operand); |
|
787 $self->{max_export_volume_size} = $operand; |
|
788 } |
|
789 elsif ($keyWord =~ /^disallow_unclassified_source$/) { |
|
790 $self->{disallow_unclassified_source} = 1; |
|
791 } |
|
792 elsif ($keyWord =~ /^disable_win32_exten[ts]ions$/) { |
|
793 $self->{disable_win32_extensions} = 1; |
|
794 } |
|
795 elsif ($keyWord =~ /^categori[sz]e_binaries$/) { |
|
796 $self->{categorise_binaries} = 1; |
|
797 } |
|
798 elsif ($keyWord =~ /^categori[sz]e_exports$/) { |
|
799 $self->{categorise_exports} = 1; |
|
800 } |
|
801 elsif ($keyWord =~ /^latestver_filter$/) { |
|
802 Utils::StripWhiteSpace(\$operand); |
|
803 require Text::Glob; |
|
804 $self->{latestver_filter} = Text::Glob::glob_to_regex($operand);; |
|
805 } |
|
806 elsif ($keyWord =~ /^required_binaries$/) { |
|
807 Utils::StripWhiteSpace(\$operand); |
|
808 (my $component, my $required, my $dummy) = split (/\s+/, $operand); |
|
809 if ($dummy or not ($component and $required)) { |
|
810 die "Error: Invalid line in \"$self->{iniFileName}\":\n\t$_\n"; |
|
811 next; |
|
812 } |
|
813 push (@{$self->{required_binaries}->{lc($component)}}, lc($required)); |
|
814 } |
|
815 #Support for target alias file |
|
816 elsif ($keyWord =~ /^no_target_alias_warning$/) { |
|
817 $self->{mustWarnTargetAliasLocation} = 0; |
|
818 } |
|
819 elsif ($keyWord =~ /^table_format$/) { |
|
820 Utils::StripWhiteSpace(\$operand); |
|
821 (my $format, my $args) = $operand =~ m/^(\w+)(.*)$/; |
|
822 Utils::StripWhiteSpace(\$args); |
|
823 $self->{table_format} = $format; |
|
824 $self->{table_format_args} = $args; |
|
825 } |
|
826 elsif ($keyWord =~ /^illegal_workspace_volumes$/) { |
|
827 Utils::StripWhiteSpace(\$operand); |
|
828 if ($operand !~ /^[a-z\s,]+$/i) { |
|
829 die "Error: Invalid line in \"$self->{iniFileName}\":\n\t$_\n"; |
|
830 } |
|
831 @{$self->{illegal_workspace_volumes}} = split /\s*,\s*/,$operand; |
|
832 } |
|
833 elsif ($keyWord =~ /^use_distribution_policy_files_first/) { |
|
834 $self->{use_distribution_policy_files_first} = 1; |
|
835 } |
|
836 elsif ($keyWord =~ /^csv_separator$/) { |
|
837 Utils::StripWhiteSpace(\$operand); |
|
838 $self->{csv_separator} = $operand; |
|
839 } |
|
840 elsif ($keyWord =~ /^sbs_version$/) { |
|
841 Utils::StripWhiteSpace(\$operand); |
|
842 $self->{sbs_version} = $operand; |
|
843 } |
|
844 else { |
|
845 die "Error: Unknown keyword \"$keyWord\" in \"$self->{iniFileName}\"\n"; |
|
846 } |
|
847 } |
|
848 |
|
849 close (INI); |
|
850 |
|
851 if ($self->{warnIniLocation}) { |
|
852 if (defined $$envDir){ |
|
853 print "Warning: \"$$iniName\" not found in \"$$envDir\", using version found in \"$$binDir\"\n"; |
|
854 } else { |
|
855 print "Warning: Using \"$$iniName\" version found in \"$$binDir\"\n"; |
|
856 } |
|
857 print " Use the keyword \"no_ini_location_warning\" to disable this warning.\n"; |
|
858 } |
|
859 } |
|
860 |
|
861 sub ReadTargetAliasFile { |
|
862 my $self = shift; |
|
863 |
|
864 if (-e $self->{targetAliasName}) { |
|
865 open (ALIAS, $self->{targetAliasName}) or die "Unable to open \"$self->{targetAliasName}\" for reading: $!\n"; |
|
866 # %allValuesSeenSoFar is a temporary hash of all the values seen so far |
|
867 my %allValuesSeenSoFar = (); |
|
868 # %aliasMap is the final hash of keys to values with all aliases expanded out |
|
869 my %aliasMap = (); |
|
870 $self->{alias_map} = {}; |
|
871 while (local $_ = <ALIAS>) { |
|
872 # Remove line feed, white space and comments. |
|
873 chomp; |
|
874 s/^\s*$//; |
|
875 s/(?<!\\)#.*//; # remove comments unless they are immediately preceded by \ (negative lookbehind assertion) |
|
876 s/\\#/#/g; # now remove backslashes before # signs |
|
877 if ($_ eq '') { |
|
878 # Nothing left. |
|
879 next; |
|
880 } |
|
881 my $keyWord; # The key field |
|
882 my @valueList; # The list of values as read from the line. |
|
883 my %seen = (); # Temporary hash for making values on the line unique |
|
884 if (/^\s*(\S+)\s+(.+)/) { |
|
885 # Uppercase significant |
|
886 $keyWord = uc($1); |
|
887 @valueList = split /\s+/, uc($2); |
|
888 # Check the key for: |
|
889 # A key that has been seen as already as a value i.e. a forward reference - fatal error |
|
890 # A key that has been seen as already as a key i.e. a duplicate key - fatal error |
|
891 if (exists $allValuesSeenSoFar{$keyWord}) { |
|
892 die "Fatal error: Line \"$_\" in $self->{targetAliasName} has forward reference to \"$keyWord\"\n"; |
|
893 } |
|
894 elsif (exists $self->{alias_map}->{$keyWord}) { |
|
895 die "Fatal error: Line \"$_\" in $self->{targetAliasName} has duplicate key \"$keyWord\"\n"; |
|
896 } |
|
897 # Check for: |
|
898 # Circular references - fatal error |
|
899 # Duplicates in the value list - warn and ignore |
|
900 foreach my $value (@valueList) { |
|
901 if ($value eq $keyWord) { |
|
902 die "Fatal error: Line \"$_\" in $self->{targetAliasName} has circular reference in \"$keyWord\"\n" |
|
903 } |
|
904 elsif (exists $seen{$value}) { |
|
905 print "Warning Line \"$_\" in $self->{targetAliasName} has duplicate value entry \"$value\" in key $keyWord\n"; |
|
906 } |
|
907 else { |
|
908 # Add to seen map and uniqueList |
|
909 $seen{$value} = 1; |
|
910 $allValuesSeenSoFar{$value} = 1; |
|
911 } |
|
912 } |
|
913 my @resolvedList = (); # Resolved aliases |
|
914 # Check for the special use of the value '<EMPTY>' |
|
915 # If this is present then there must be no other values. |
|
916 if (exists $seen{"<EMPTY>"}) { |
|
917 if (scalar (keys %seen) > 1) { |
|
918 die "Fatal error: Multiple targets in list declared \"<EMPTY>\" for alias \"$keyWord\"\n"; |
|
919 } |
|
920 } else { |
|
921 # Now can expand the unique list by resolving aliases against existing keys |
|
922 foreach my $uniqueLine (keys %seen) { |
|
923 if (exists $self->{alias_map}->{$uniqueLine}) { |
|
924 # Expand the list to resolve the aliases |
|
925 push(@resolvedList, @{$self->{alias_map}->{$uniqueLine}}); |
|
926 } |
|
927 else { |
|
928 # No alias resolution required, just add it |
|
929 push(@resolvedList, $uniqueLine); |
|
930 } |
|
931 } |
|
932 } |
|
933 # Add the resolved list to the aliasMap |
|
934 push( @{$self->{alias_map}->{$keyWord}}, @resolvedList); |
|
935 } |
|
936 else { |
|
937 # A line with no value is illegal. |
|
938 # Grab the key word |
|
939 if (/^\s*(\S+)/) { |
|
940 # Make uppercase as HasTargetPlatforms(), TargetPlatforms() |
|
941 # expects uppercase keys |
|
942 $keyWord = uc($1); |
|
943 } else { |
|
944 die "Fatal error: Fatal parser error.\n" |
|
945 } |
|
946 die "Fatal error: No targets detected for \"$keyWord\"\n" |
|
947 } |
|
948 unless (defined $keyWord) { |
|
949 die "Error: Invalid line in \"$self->{targetAliasName}\":\n\t$_\n"; |
|
950 next; |
|
951 } |
|
952 } |
|
953 close (ALIAS); |
|
954 } else { |
|
955 # Failed to find target alias file |
|
956 return 0; |
|
957 } |
|
958 return 1; # Success at reading the file |
|
959 } |
|
960 |
|
961 # Support for target alias file |
|
962 # Returns 1 if target platforms exist for a given alias |
|
963 # or 0 if no target platforms exist for a given alias |
|
964 sub HasTargetPlatforms { |
|
965 my $self = shift; |
|
966 my $alias = shift; |
|
967 $alias = uc($alias); |
|
968 $self->CheckAliasWarning(); |
|
969 if (exists $self->{alias_map}) { |
|
970 if (exists $self->{alias_map}->{$alias}) { |
|
971 return 1; |
|
972 } |
|
973 } |
|
974 return 0; |
|
975 } |
|
976 |
|
977 # Support for target alias file |
|
978 # Returns the arrary of target platforms for a given alias |
|
979 # or undef if no target platforms for a given alias |
|
980 sub TargetPlatforms { |
|
981 my $self = shift; |
|
982 my $alias = shift; |
|
983 $self->CheckAliasWarning(); |
|
984 $alias = uc($alias); |
|
985 if (exists $self->{alias_map}) { |
|
986 if (exists $self->{alias_map}->{$alias}) { |
|
987 return $self->{alias_map}->{$alias}; |
|
988 } |
|
989 } |
|
990 # Nothing found so return the callers argument |
|
991 return [$alias]; |
|
992 } |
|
993 |
|
994 sub CheckAliasWarning { |
|
995 my $self = shift; |
|
996 if ($self->{mustWarnTargetAliasLocation} == 1) { |
|
997 print "Warning: \"$self->{targetAliasName}\" not found.\n"; |
|
998 print " Use the keyword \"no_target_alias_warning\" to disable this warning.\n"; |
|
999 } |
|
1000 $self->{mustWarnTargetAliasLocation} = 0; |
|
1001 } |
|
1002 |
|
1003 sub UseDistributionPolicyFilesFirst { |
|
1004 my $self = shift; |
|
1005 return !!$self->{use_distribution_policy_files_first}; |
|
1006 } |
|
1007 |
|
1008 sub CsvSeparator { |
|
1009 my $self = shift; |
|
1010 |
|
1011 if (defined $self->{csv_separator}) { |
|
1012 return $self->{csv_separator}; |
|
1013 } |
|
1014 |
|
1015 return ','; |
|
1016 } |
|
1017 |
|
1018 1; |
|
1019 |
|
1020 __END__ |
|
1021 |
|
1022 =head1 NAME |
|
1023 |
|
1024 IniData.pm - Provides an interface to the data contained in reltools.ini. |
|
1025 |
|
1026 =head1 INTERFACE |
|
1027 |
|
1028 =head2 New |
|
1029 |
|
1030 Expects to find a file named F<reltools.ini> in the release tools directory, dies if it can't. Parses this file according to the following keywords / value pairs: |
|
1031 |
|
1032 require_internal_versions |
|
1033 ignore_source_filter_errors |
|
1034 no_ini_location_warning |
|
1035 disallow_unclassified_source |
|
1036 categorise_binaries |
|
1037 categorise_exports |
|
1038 html_notes |
|
1039 archive_path <archive_name> <archive_path> [<remote_archive_path>] |
|
1040 diff_tool <tool_name> |
|
1041 export_data_file <file_name> |
|
1042 archive_path_file <file_name> |
|
1043 source_map <archive_source_directory> <local_source_directory> |
|
1044 remote_site_type <server_type> |
|
1045 remote_host <host_name> |
|
1046 remote_username <user_name> |
|
1047 remote_password <pass_word> |
|
1048 remote_logs_dir <path> |
|
1049 pasv_transfer_mode |
|
1050 ftp_server_supports_resume |
|
1051 ftp_timeout <time_in_seconds> |
|
1052 ftp_reconnect_attempts <positive_integer> |
|
1053 proxy <host_name> |
|
1054 proxy_username <user_name> |
|
1055 proxy_password <pass_word> |
|
1056 pgp_tool <tool_name> |
|
1057 pgp_encryption_key <keyid> |
|
1058 pgp_config_path <dir_name> |
|
1059 ignore_binary <wild_file_name> |
|
1060 required_binaries default wins_udeb |
|
1061 required_binaries default thumb_urel |
|
1062 table_format <table_format module> |
|
1063 csv_separator <csv_separator_character> |
|
1064 sbs_version <symbian_build_system> |
|
1065 |
|
1066 It assumes # indicates the start of a comment, unless it is preceded by \. |
|
1067 |
|
1068 =head2 DiffTool |
|
1069 |
|
1070 Returns the name of the differencing tool specified with the C<diff_tool> keyword. |
|
1071 |
|
1072 =head2 RequireInternalVersions |
|
1073 |
|
1074 Returns true or false depending on whether the C<require_internal_versions> keyword has been specified. |
|
1075 |
|
1076 =head2 IgnoreSourceFilterErrors |
|
1077 |
|
1078 Returns true or false depending on whether the C<ignore_source_filter_errors> keyword has been specified. |
|
1079 |
|
1080 =head2 RemoteSiteType |
|
1081 |
|
1082 Returns the type of server hosting the projects remote release archive. Currently this will return either C<'FTP'>, C<'FTP::Proxy'>, C<'NetDrive'>, C<'NetDrive::MultiVolumeExport'> or C<'NetDrive::MultiVolumeImport'>. The default return value is C<'FTP'> if not set. |
|
1083 |
|
1084 =head2 RemoteHost |
|
1085 |
|
1086 Returns the host address of the project's remote site. If the remote site is an ftp server this will be an ftp address; if it is a network drive then the return value will be a UNC path. |
|
1087 |
|
1088 =head2 RemoteUsername |
|
1089 |
|
1090 Returns the username for the project's remote site. |
|
1091 |
|
1092 =head2 RemotePassword |
|
1093 |
|
1094 Returns the password for the project's remote site. |
|
1095 |
|
1096 =head2 RemoteLogsDir |
|
1097 |
|
1098 Returns the directory on the project's remote site where release notification logs are to be written. |
|
1099 |
|
1100 =head2 PasvTransferMode |
|
1101 |
|
1102 Returns true or false depending on whether the C<pasv_transfer_mode> keyword has been specified. |
|
1103 |
|
1104 =head2 FtpServerSupportsResume |
|
1105 |
|
1106 Returns true or false depending on whether the C<ftp_server_supports_resume> keyword has been specified. |
|
1107 |
|
1108 =head2 FtpTimeout |
|
1109 |
|
1110 Returns the timeout in seconds allowed before dropping the connection to the FTP server |
|
1111 |
|
1112 =head2 FtpReconnectAttempts |
|
1113 |
|
1114 Returns the number of attempts to reconnect to the FTP site if the connection is dropped |
|
1115 |
|
1116 =head2 Proxy |
|
1117 |
|
1118 Returns the FTP address of a proxy server used to connect to the project's FTP site. |
|
1119 |
|
1120 =head2 ProxyUsername |
|
1121 |
|
1122 Returns the username for a proxy server used to connect to the project's FTP site. |
|
1123 |
|
1124 =head2 ProxyPassword |
|
1125 |
|
1126 Returns the password for a proxy server used to connect to the project's FTP site. |
|
1127 |
|
1128 =head2 RemoteSite |
|
1129 |
|
1130 Tries to create a RemoteSite object appropriate to the data in the iniData, and return it. Caches the RemoteSite object so that it is only created once. |
|
1131 |
|
1132 =head2 MaxExportVolumeSize |
|
1133 |
|
1134 Returns the value specified by the keyword C<max_export_volume_size>. If this has not been specified, returns 639 * 1024 * 1024. |
|
1135 |
|
1136 =head2 PgpTool |
|
1137 |
|
1138 Returns the command line PGP client used to encrypt and decrypt releases. |
|
1139 Currently this will return either C<'PGP'> for NAI Inc. PGP or C<'GPG'> for GNU Privacy Guard. The default return value is C<'PGP'> if not set. |
|
1140 |
|
1141 =head2 PgpEncryptionKeys |
|
1142 |
|
1143 Returns a reference to an array of PGP key ids (an 8 digit hexadecimal number) used to encrypt all release files before exporting to the remote site. Typically these values will correspond to the local sites project PGP keys so that the user may decrypt their own releases. |
|
1144 |
|
1145 =head2 PgpConfigPath |
|
1146 |
|
1147 Returns the directory where the users PGP configuration and keyring files are stored. |
|
1148 |
|
1149 =head2 ArchivePathFile |
|
1150 |
|
1151 Returns the name of the archive path file. |
|
1152 |
|
1153 =head2 ExportDataFile |
|
1154 |
|
1155 Returns the name of the export data file. |
|
1156 |
|
1157 =head2 LocalArchivePath |
|
1158 |
|
1159 Expects to be passed a component name. Returns the path to the component's local archive (generally on a LAN share). |
|
1160 |
|
1161 =head2 RemoteArchivePath |
|
1162 |
|
1163 Expects to be passed a component name. Returns the path to the component's remote archive (may be either on a Network share or an FTP site). |
|
1164 |
|
1165 =head2 ListArchiveComponents |
|
1166 |
|
1167 Returns a list of component names specified in the archive path file. One of these may be 'default' (if this has been specified). The directories pointed to by this may contain multiple components. |
|
1168 |
|
1169 =head2 BinariesToIgnore |
|
1170 |
|
1171 Returns a reference to a list of binaries to be ignored when scanning the F<\epoc32> tree. These may contain the C<*> wild character. |
|
1172 |
|
1173 =head2 DisallowUnclassifiedSource |
|
1174 |
|
1175 Returns false unless the C<disallow_unclassified_source> keyword has been specified. |
|
1176 |
|
1177 =head2 Win32ExtensionsDisabled |
|
1178 |
|
1179 Returns false unless the C<disable_win32_extensions> keyword has been specified. (Spelling C<disable_win32_extentions> also OK!) |
|
1180 |
|
1181 =head2 CategoriseBinaries |
|
1182 |
|
1183 Returns false unless the C<categorise_binaries> keyword has been specified. |
|
1184 |
|
1185 =head2 CategoriseExports |
|
1186 |
|
1187 Returns false unless the C<categorise_exports> keyword has been specified. |
|
1188 |
|
1189 =head2 TableFormatter |
|
1190 |
|
1191 Returns a TableFormatter object, which can be used to print a table. |
|
1192 |
|
1193 =head2 RequiredBinaries |
|
1194 |
|
1195 Expects to be passed a component name. Returns the required binaries for that component if any were specified using the C<required_binaries> keyword. If none were, then those specified using C<required_binaries default> are returned. If there are none of those either, then C<undef> is returned - this means that all binaries should be used. |
|
1196 |
|
1197 =head2 PathData |
|
1198 |
|
1199 Returns a PathData object appropriate to the path configuration data in the ini file. This may be a PathData::ProjectBased or a PathData::ComponentBased object. |
|
1200 |
|
1201 =head2 FromMapping |
|
1202 |
|
1203 Returns an array of <archive_source_directory> mappings. If there are no mappings defined an undefined value is returned. |
|
1204 |
|
1205 =head2 ToMapping |
|
1206 |
|
1207 Returns an array of <local_source_directory> mappings. If there are no mappings defined an undefined value is returned. |
|
1208 |
|
1209 =head2 HasMappings |
|
1210 |
|
1211 Returns false if no mappings are defined. Otherwise returns true. |
|
1212 |
|
1213 =head2 PerformMapOnFileName |
|
1214 |
|
1215 Reads a filename and takes all mappings defined into consideration with <archive_source_directory> being mapped to <local_source_directory>. Returns the new filename, with the mappings processed. |
|
1216 |
|
1217 =head2 PerformReverseMapOnFileName |
|
1218 |
|
1219 Reads a filename and takes all mappings defined into consideration with <local_source_directory> being mapped to <archive_source_directory>. Returns the new filename, with the mappings processed. |
|
1220 |
|
1221 =head2 CheckMappingPath |
|
1222 |
|
1223 Expects a mapping path which is checked. Any problems with the path are reported and the program exits. Otherwise returns the checked mapping path. |
|
1224 |
|
1225 =head2 ExtractMapping |
|
1226 |
|
1227 Is used to extract and store the local and archive mappings directories as defined. If an usage error is encountered, an error message is displayed and the program exits. |
|
1228 |
|
1229 =head2 CheckFileNameForMappingClash |
|
1230 |
|
1231 Is used to check if any of the mappings defined clash with the filename passed. If there is a clash an error message is shown and the program exits. |
|
1232 |
|
1233 =head2 HasTargetPlatforms |
|
1234 |
|
1235 Returns true if there is are any target platforms for a given alias. False otherwise. |
|
1236 |
|
1237 =head2 TargetPlatforms |
|
1238 |
|
1239 Returns a reference to a list containing either the platforms for a given alias or the alias itself (i.e. not an alias but a platform name). |
|
1240 |
|
1241 =head2 CsvSeparator |
|
1242 |
|
1243 Returns the separator to be used for CSV files, which by default is a comma ','. Depending on the locale, the separator may be different. The user can specify the separator required by using the C<csv_separator> keyword. |
|
1244 |
|
1245 |
|
1246 =head1 KNOWN BUGS |
|
1247 |
|
1248 None. |
|
1249 |
|
1250 =head1 COPYRIGHT |
|
1251 |
|
1252 Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
1253 All rights reserved. |
|
1254 This component and the accompanying materials are made available |
|
1255 under the terms of the License "Eclipse Public License v1.0" |
|
1256 which accompanies this distribution, and is available |
|
1257 at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
1258 |
|
1259 Initial Contributors: |
|
1260 Nokia Corporation - initial contribution. |
|
1261 |
|
1262 Contributors: |
|
1263 |
|
1264 Description: |
|
1265 |
|
1266 |
|
1267 =cut |