1 # |
|
2 # Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: A tool that install widgets and dtd files. |
|
15 # Tool is mainly meant to be used via dtd.mk makefile template, |
|
16 # but can be run as such also. |
|
17 # |
|
18 |
|
19 use strict; |
|
20 |
|
21 #Tools path |
|
22 use constant LIBPATH => '/epoc32/tools'; |
|
23 use lib LIBPATH; |
|
24 |
|
25 use Cwd; |
|
26 use Getopt::Long; |
|
27 use Convert_file; # for .dtd to .loc file conversion |
|
28 use File::Copy; |
|
29 use File::Find; # for finding |
|
30 use File::Path; # mkpath |
|
31 use File::Basename; # fileparse |
|
32 |
|
33 if ( $#ARGV < 1) |
|
34 { |
|
35 print <<USAGE; |
|
36 Usage: dtd_installer.pl -n dtd_name [-t type][-l dtd_location] [-s sub_folder_name] [-o output_location] [-a action_type] [-f force_create] [-d debug] |
|
37 -n: widget or dtd (switch_loc) file name |
|
38 -t: optional, default type is dtd and other possibility is widget |
|
39 -l: optional, input path location, |
|
40 default for widget type is \\epoc32\\data\\z\\resource\\homescreen |
|
41 default for dtd is \\epoc32\\include\\domain\\<layer>\\loc |
|
42 -s: optional, for widgets only, default are xuikon and hsps |
|
43 -o: optional, default is \\epoc32\\release\\winscw\\udeb\\z\\private\\200159c0\\install |
|
44 -a: optional, default is build other possible are what and clean |
|
45 -f: optional, for widgets only, themeinstaller is always run for xuikon, even switch loc file don\'t exist |
|
46 -d: optional, for debugging purposes (e.g. temporary folders aren't deleted) |
|
47 |
|
48 Example how to run for dtd files only: |
|
49 dtd_installer.pl -n matrixmenudata -o \\epoc32\\data\\z\\private\\200113DD\\content |
|
50 Example how to run for one widget: |
|
51 dtd_installer.pl -n view -t type widget |
|
52 Example how to run for all widgets: |
|
53 dtd_installer.pl -n all_widgets -t type widget -d yes |
|
54 |
|
55 USAGE |
|
56 exit -1; |
|
57 } |
|
58 |
|
59 my ($dtd_name, $dtd_type, $dtd_location, $sub_folder_name, $output_location, $action_type, $force_create, $debug, $what_output_file); |
|
60 my (@all_dirs, @find_files, @files_to_convert); |
|
61 my @sub_folders=("xuikon","hsps"); |
|
62 my @layers=("\\epoc32\\include\\domain\\osextensions\\loc", "\\epoc32\\include\\domain\\middleware\\loc", "\\epoc32\\include\\domain\\applications\\loc", "\\epoc32\\include\\platform\\loc", "\\epoc32\\include\\platform\\mw\\loc", "\\epoc32\\include\\platform\\app\\loc"); |
|
63 my $themeinstaller_tool = "\\epoc32\\tools\\themeinstaller\\themeinstaller.bat"; |
|
64 my $themeinstaller_property_file = "\\epoc32\\tools\\themeinstaller\\data\\widgetinstaller.prop"; |
|
65 |
|
66 # Set this to 1 if you need to debug the script |
|
67 # $debug = 1; |
|
68 |
|
69 GetOptions( |
|
70 'n=s' => \$dtd_name, |
|
71 't=s' => \$dtd_type, |
|
72 'l=s' => \$dtd_location, |
|
73 's=s' => \$sub_folder_name, |
|
74 'o=s' => \$output_location, |
|
75 'a=s' => \$action_type, |
|
76 'd=s' => \$debug, |
|
77 'f=s' => \$force_create ); |
|
78 |
|
79 check_options(); |
|
80 |
|
81 if (($action_type eq "what") && (-e $what_output_file)) { |
|
82 open( WHAT, $what_output_file) or die $!; |
|
83 while( <WHAT> ){ |
|
84 print ; |
|
85 } |
|
86 close WHAT; |
|
87 exit; |
|
88 } elsif (($action_type eq "clean") && (-e $what_output_file)) { |
|
89 unlink $what_output_file; |
|
90 } |
|
91 |
|
92 if ($dtd_type eq "widget") { |
|
93 if ((lc $dtd_name) eq "all_widgets") { |
|
94 # read all widget names from given directory |
|
95 opendir(SDIR, $dtd_location) or die("ERROR: dtd_installer.pl, can not open $dtd_location\n"); |
|
96 @all_dirs = grep !/^\.\.?$/, readdir SDIR; |
|
97 closedir(SDIR); |
|
98 if (!@all_dirs) { |
|
99 warn"ERROR: dtd_installer.pl, couldn't find any widgets:\n"; |
|
100 die; |
|
101 } |
|
102 foreach my $temp_dtd_name (@all_dirs) { |
|
103 $dtd_name = $temp_dtd_name; |
|
104 my $dir = "${dtd_location}\\${dtd_name}"; |
|
105 if (-d $dir) { # Calling process_widget sub routine for every directory |
|
106 process_widget(); |
|
107 } |
|
108 } |
|
109 } else { # Only one widget processed |
|
110 process_widget(); |
|
111 } |
|
112 } else { |
|
113 # Run only .loc to .dtd conversion for non widgets |
|
114 process_dtd($output_location, $dtd_name); |
|
115 } |
|
116 |
|
117 sub process_widget |
|
118 { |
|
119 |
|
120 foreach my $sub_f (@sub_folders) { |
|
121 my @lang_dirs; |
|
122 if ($debug) { print "Current subfolder:\n $sub_f\n"; } |
|
123 ${sub_folder_name} = $sub_f; |
|
124 if ($debug) { print "Processing widget:\n${dtd_location}\\${dtd_name}\n"; } |
|
125 |
|
126 my $current_time = time; |
|
127 my $full_dtd_input_path = "${dtd_location}\\${dtd_name}\\${sub_folder_name}"; |
|
128 my $full_dtd_output_path = "${output_location}\\${dtd_name}\\${sub_folder_name}"; |
|
129 my $temp_path = "${dtd_location}\\${dtd_name}\\temp"; |
|
130 my $temp_loc_path = "${dtd_location}\\${dtd_name}\\${sub_folder_name}\\temp"; |
|
131 my $temp_dtd_path = "${temp_path}\\$current_time"; |
|
132 my $temp_loc_files_path = "${temp_loc_path}\\$current_time"; |
|
133 my $no_success = 1; |
|
134 my $count = 0; |
|
135 |
|
136 while ($no_success) { # make sure that temporary directory isn't already in the use |
|
137 undef $no_success; |
|
138 $current_time = time; |
|
139 $temp_dtd_path = "${temp_path}\\$current_time"; |
|
140 mkpath $temp_dtd_path or $no_success=1; |
|
141 sleep 1; |
|
142 $count++; |
|
143 if ($count > 100 ) { warn: "ERROR: dtd_installer.pl, couldn't create temp directory $temp_dtd_path !!!\nDtd_installer\.pl script stopped\n"; die;} |
|
144 } |
|
145 $count = 0; |
|
146 $no_success = 1; |
|
147 while ($no_success) { # make sure that temporary directory isn't already in the use |
|
148 undef $no_success; |
|
149 $current_time = time; |
|
150 $temp_loc_files_path = "${temp_loc_path}\\$current_time"; |
|
151 mkpath $temp_loc_files_path or $no_success=1; |
|
152 sleep 1; |
|
153 $count++; |
|
154 if ($count > 100 ) { warn: "ERROR: dtd_installer.pl, couldn't create temp directory $temp_loc_files_path!!!\nDtd_installer\.pl script stopped\n"; die;} |
|
155 } |
|
156 |
|
157 if ($debug) { print "Full dtd input path:\n$full_dtd_input_path\n"; } |
|
158 if ($debug) { print "Full dtd output path:\n$full_dtd_output_path\n"; } |
|
159 opendir(SDIR, $full_dtd_input_path) or die("ERROR: dtd_installer.pl, can not open $full_dtd_input_path\n"); |
|
160 @lang_dirs = grep !/^\.\.?$/, readdir SDIR; |
|
161 closedir(SDIR); |
|
162 |
|
163 |
|
164 if (${sub_folder_name} eq "xuikon") { # Copy engineering english files always to 00 folder |
|
165 copy_files($full_dtd_input_path,"${temp_loc_files_path}\\00"); |
|
166 } else{ #hsps folder |
|
167 copy_files($full_dtd_input_path,"${full_dtd_output_path}\\00"); |
|
168 } |
|
169 |
|
170 |
|
171 foreach my $lang_id (@lang_dirs) { # generate localized .dtd files |
|
172 |
|
173 my $dtd_temp = "${full_dtd_input_path}\\${lang_id}"; |
|
174 if ((-f $dtd_temp) && ($lang_id =~ /.dtd/i) ) { # running loc to dtd for all .dtd files |
|
175 if ($debug) { print "Dtd file found:\n$dtd_temp\n"; } |
|
176 |
|
177 if (${sub_folder_name} eq "xuikon") { # generate xuikon .dtd files to temp path |
|
178 if ($debug) { print "Widget type DTD, xuikon subfolder\n"; } |
|
179 process_dtd($temp_loc_files_path, $lang_id); |
|
180 } else{ #hsps folder |
|
181 if ($debug) { print "Widget type DTD, hsps subfolder\n"; } |
|
182 process_dtd($full_dtd_output_path, $lang_id); |
|
183 } |
|
184 } elsif ((${sub_folder_name} eq "xuikon") && ($force_create ne "") && (-d $dtd_temp)) { |
|
185 copy_files($dtd_temp,"${temp_loc_files_path}\\${lang_id}"); |
|
186 } |
|
187 } |
|
188 |
|
189 if (${sub_folder_name} eq "xuikon") { # generate localized files |
|
190 if (!(-f $themeinstaller_tool)) { die("ERROR: dtd_installer.pl, can not find themeinstaller: $themeinstaller_tool\n"); } |
|
191 if (!(-f $themeinstaller_property_file)) { die("ERROR: dtd_installer.pl, can not find themeinstaller property file: $themeinstaller_property_file\n"); } |
|
192 |
|
193 if (-d $temp_loc_files_path) { |
|
194 opendir(SDIR, $temp_loc_files_path) or die("ERROR: dtd_installer.pl, can not open $temp_loc_files_path\n"); |
|
195 @lang_dirs = grep !/^\.\.?$/, readdir SDIR; |
|
196 closedir(SDIR); |
|
197 |
|
198 foreach my $lang_id (@lang_dirs) { |
|
199 my $lang_dir = "$temp_loc_files_path\\$lang_id"; |
|
200 if ($debug) { print"Language directory:\n$lang_dir\n"; } |
|
201 if (-d $lang_dir) { # Running themeinstaller for all language folders in temp path |
|
202 my $temp_dir = "$temp_dtd_path\\$lang_id"; |
|
203 copy_files($full_dtd_input_path, "$temp_dir"); |
|
204 my $lang_temp_dir = "$full_dtd_input_path\\$lang_id"; |
|
205 if (-d $lang_temp_dir) { |
|
206 copy_files("$lang_temp_dir", "$temp_dir"); |
|
207 } |
|
208 copy_files("$temp_loc_files_path\\$lang_id", "$temp_dir"); |
|
209 if (($action_type eq "build") || ($debug)) { |
|
210 print ("Calling themeinstaller: \n$themeinstaller_tool $temp_dtd_path\\${lang_id}\\${dtd_name}.dat $temp_dtd_path\\${lang_id} -prop:${themeinstaller_property_file}\n"); |
|
211 system ("$themeinstaller_tool","$temp_dtd_path\\${lang_id}\\${dtd_name}.dat","$temp_dtd_path\\${lang_id}", "-prop:${themeinstaller_property_file}"); |
|
212 } else { |
|
213 system ("$themeinstaller_tool","$temp_dtd_path\\${lang_id}\\${dtd_name}.dat","$temp_dtd_path\\${lang_id}", "-prop:${themeinstaller_property_file}", ">$temp_dtd_path\\${lang_id}\\themeinstaller.log", "2>&1" ); |
|
214 } |
|
215 copy_files("$temp_dir", "$full_dtd_output_path\\$lang_id", "recursive"); |
|
216 } |
|
217 } |
|
218 } |
|
219 } |
|
220 |
|
221 if ($debug) { |
|
222 print "Widget processed: ${dtd_name} \n"; |
|
223 } else { |
|
224 # Remove all temporary directories |
|
225 if (-d $temp_dtd_path) { rmtree ($temp_dtd_path); } |
|
226 if (-d $temp_loc_files_path) { rmtree ($temp_loc_files_path); } |
|
227 rmdir $temp_path; |
|
228 rmdir $temp_loc_path; |
|
229 } |
|
230 } |
|
231 } |
|
232 |
|
233 sub process_dtd { |
|
234 |
|
235 my $output_path = shift; |
|
236 my $switch_loc_name = shift; |
|
237 $switch_loc_name =~ s/.dtd//i;; # remove the .dtd extension |
|
238 my $input_path = $dtd_location; |
|
239 my ($found, $loc_file); |
|
240 if ($action_type eq "build") { print "Used switch loc file name:\n${switch_loc_name}\n"; } |
|
241 if ($debug) { print "Used input path:\n${input_path}\n"; } |
|
242 if ($debug) { print "Used output path:\n${output_path}\n"; } |
|
243 |
|
244 foreach (@layers) { |
|
245 $input_path = $_; |
|
246 if ($debug) { print("Used switch loc file path:\n${input_path}\n"); } |
|
247 my $loc_file = "${input_path}\\${switch_loc_name}.loc"; |
|
248 if (-e $loc_file) { |
|
249 convert_locs_to_dtds($loc_file, $input_path, $output_path); |
|
250 $found = "yes"; |
|
251 } |
|
252 } |
|
253 if ($found ne "yes") { |
|
254 warn "ERROR: dtd_installer.pl, no .loc file found:\n${switch_loc_name}.loc\n"; |
|
255 } |
|
256 } |
|
257 |
|
258 sub check_options { |
|
259 |
|
260 if ($dtd_name eq "") { |
|
261 warn: "ERROR: dtd_installer.pl, no widget name given!!!\nDtd_installer\.pl script stopped\n"; |
|
262 die; |
|
263 } |
|
264 |
|
265 if ($dtd_type eq "") { |
|
266 $dtd_type = "dtd"; |
|
267 } |
|
268 |
|
269 if ($dtd_location eq "") { |
|
270 if ($dtd_type eq "widget") { |
|
271 $dtd_location = "\\epoc32\\data\\z\\resource\\homescreen"; |
|
272 } |
|
273 } else { |
|
274 if ($dtd_type eq "dtd") { |
|
275 undef @layers; |
|
276 @layers[0]=${dtd_location}; |
|
277 } |
|
278 } |
|
279 |
|
280 if ($output_location eq "") { |
|
281 $output_location = "\\epoc32\\release\\winscw\\udeb\\z\\private\\200159c0\\install"; |
|
282 } |
|
283 |
|
284 if (${sub_folder_name} ne ""){ |
|
285 undef @sub_folders; |
|
286 @sub_folders[0]=${sub_folder_name}; |
|
287 } |
|
288 |
|
289 if ($action_type eq "") { |
|
290 $action_type = "build"; |
|
291 } |
|
292 |
|
293 $dtd_location =~ s/\//\\/g; #Change / marks to \ |
|
294 $output_location =~ s/\//\\/g; #Change / marks to \ |
|
295 $what_output_file = $output_location; |
|
296 $what_output_file =~ s/\\/_/g; #Change \ marks to _ |
|
297 $what_output_file = "\\epoc32\\build\\dtd_installer\\" . $what_output_file . $dtd_name . ".txt"; |
|
298 if ( !-d "/epoc32/build/dtd_installer") { mkdir("/epoc32/build/dtd_installer"); } |
|
299 if ($debug) { print "Output what file: $what_output_file\n"; } |
|
300 } |
|
301 |
|
302 # This subroutine moves files to/from temporary themeinstaller location. |
|
303 sub copy_files { |
|
304 my $in_path = shift; |
|
305 my $out_path = shift; |
|
306 my $recursive = shift; |
|
307 if ($debug) { print "Copying from: $in_path\n"; } |
|
308 if ($debug) { print "To: $out_path\n"; } |
|
309 |
|
310 if ($recursive) { |
|
311 find( \&getFiles, $in_path ); |
|
312 } else { |
|
313 opendir(SDIR, $in_path) or die("ERROR: dtd_installer.pl, can not open $in_path\n"); |
|
314 @find_files = grep !/^\.\.?$/, readdir SDIR; |
|
315 closedir(SDIR); |
|
316 } |
|
317 |
|
318 foreach my $file (@find_files) { |
|
319 my $in_file = "${in_path}\\${file}"; |
|
320 my $out_file= "${out_path}\\${file}"; |
|
321 if ($recursive) { |
|
322 $in_file = $file; |
|
323 $file =~ /.*\\(.*)\\.*\\.*\\.*\\(.*)\\(.*)/i; |
|
324 my $temp=$1; # lang code |
|
325 my $temp2=$3; # file name |
|
326 if ((lc $2) eq "sources") { |
|
327 $out_file = "${out_path}\\$2\\$3"; |
|
328 } else { |
|
329 if (length($temp) > 4) { #skip extra files |
|
330 next; |
|
331 } |
|
332 while (length($temp) < 4){ $temp = "0".$temp; } |
|
333 $temp2 =~ s/\d{4}/$temp/g; # change .odt filename for correct lang |
|
334 $out_file = "${out_path}\\$temp2"; |
|
335 } |
|
336 } |
|
337 if ($debug) { print "Copying file from: $in_file\n"; } |
|
338 if ($debug) { print "To: $out_file\n"; } |
|
339 if (-f $in_file){ |
|
340 if ($action_type eq "build") { |
|
341 if ((!($out_file =~ /\\temp\\/i))) {write_what_file("$out_file")}; |
|
342 xcopy($in_file,$out_file); |
|
343 } elsif ($action_type eq "clean") { |
|
344 if (!($out_file =~ /\\temp\\/i)) { |
|
345 unlink $out_file; |
|
346 my $temp_dir_path = $out_file; |
|
347 $temp_dir_path =~ /(.*)\\.*/; |
|
348 $temp_dir_path = $1; |
|
349 rmdir $temp_dir_path; # Try to remove empty language directories |
|
350 } else { |
|
351 xcopy($in_file,$out_file); |
|
352 } |
|
353 } elsif ($action_type eq "what") { |
|
354 if (!($out_file =~ /\\temp\\/i)) { |
|
355 write_what_file("$out_file"); |
|
356 print("$out_file\n"); |
|
357 } else { |
|
358 xcopy($in_file,$out_file); |
|
359 } |
|
360 } else { |
|
361 warn ("ERROR: dtd_installer.pl, unknown action type"); |
|
362 } |
|
363 } else { |
|
364 if ($debug) { print "Not file found: $in_file\n"; } |
|
365 } |
|
366 } |
|
367 } |
|
368 |
|
369 # This subroutine converts LOC files to DTD files. Files that are |
|
370 # listed in the switch_loc file are converted to DTD files. |
|
371 |
|
372 sub convert_locs_to_dtds { |
|
373 my $switch_loc_file = shift; |
|
374 my $in_path = shift; |
|
375 my $out_path = shift; |
|
376 |
|
377 open(my $switch_loc_file_handle, "$switch_loc_file") |
|
378 or die "Can't open `$switch_loc_file' for reading: $!"; |
|
379 |
|
380 # Read localised .loc file names from used input switch loc file |
|
381 while (my $line = <$switch_loc_file_handle>) { |
|
382 chomp($line); |
|
383 if (($line =~ "include") && (!($line =~ /\<sc\//i)) && (!($line =~ /\<00\//i)) ){ # Read all lines that contains include, except sc and 00 |
|
384 $line=~ /.*\<(.*)\>.*/; |
|
385 $line=$1; |
|
386 $line =~ s/\//\\/g; #Change / marks to \ |
|
387 if ($debug) { print"Adding localised file to conversion list:\n$line\n"; } |
|
388 push @files_to_convert, $line; |
|
389 } |
|
390 } |
|
391 |
|
392 close $switch_loc_file_handle; |
|
393 |
|
394 # Process all the .loc files. |
|
395 foreach (@files_to_convert) { |
|
396 my $loc_file = "$in_path\\$_"; |
|
397 my $out_file = "$out_path\\$_"; |
|
398 $out_file =~ s/_\d{2,5}(.{4})$/$1/i; # remove the language code from the file name. |
|
399 if ($debug) { print"Trying to convert file:\n$loc_file\n"; } |
|
400 if ($debug) { print"To out file:\n$out_file\n"; } |
|
401 if (-f $loc_file) { |
|
402 if (($action_type eq "build") || ((${dtd_type} eq "widget") && (${sub_folder_name} eq "xuikon")) ) { |
|
403 #old if ((!($out_file =~ /\\temp\\/i))) {write_what_file("$out_file")}; |
|
404 xcopy($loc_file,$out_file); |
|
405 Convert_file::convert_file($out_file); |
|
406 if ((!($out_file =~ /\\temp\\/i))) { |
|
407 my $convert_out_file = $out_file; |
|
408 $convert_out_file =~ s/\.loc/\.dtd/; # replace .loc with .dtd |
|
409 write_what_file("$convert_out_file"); |
|
410 } |
|
411 if (!($debug)) { unlink $out_file; } # Delete the copied .loc file |
|
412 $out_file =~ s/\.loc/\.log/; # replace .loc with .log |
|
413 if (!($debug)) { unlink $out_file; } # Delete the conversion .log file |
|
414 } elsif ($action_type eq "clean") { |
|
415 $out_file =~ s/\.loc/\.dtd/; # replace .loc with .dtd |
|
416 unlink $out_file; # delete the output file |
|
417 my $temp_dir_path = $out_file; |
|
418 $temp_dir_path =~ /(.*)\\.*/; |
|
419 $temp_dir_path = $1; |
|
420 rmdir $temp_dir_path; # Try to remove empty language directories |
|
421 } elsif (($action_type eq "what") && (!($out_file =~ /\\temp\\/i))) { |
|
422 $out_file =~ s/\.loc/\.dtd/; # replace .loc with .dtd |
|
423 print("$out_file\n"); |
|
424 write_what_file("$out_file"); |
|
425 } |
|
426 } else { |
|
427 warn "ERROR: dtd_installer.pl, no .loc file found: $loc_file\n"; |
|
428 } |
|
429 } |
|
430 } |
|
431 |
|
432 # This subroutine is for file copying |
|
433 sub xcopy |
|
434 { |
|
435 my $source = shift; |
|
436 my $dist = shift; |
|
437 |
|
438 # if distination file exist then clear read flag |
|
439 if (-f $dist) |
|
440 { |
|
441 chmod ($dist , 0755); |
|
442 } |
|
443 else |
|
444 { |
|
445 my($n, $d, $ext) = fileparse($dist, '\..*'); |
|
446 # check weather distination directory exist or not. If directory doesn't exist then create it. |
|
447 -d $d || mkpath($d, 0, 0x755); |
|
448 } |
|
449 |
|
450 # copy source to distination |
|
451 copy($source,$dist); |
|
452 } |
|
453 |
|
454 # read files from given path to filelist |
|
455 sub getFiles { |
|
456 my $file_name = $File::Find::name; |
|
457 $file_name =~ s/\//\\/g; #Change / marks to \ |
|
458 chomp $file_name; |
|
459 next if ( -d $file_name ); # Skip directories |
|
460 next if ((!($file_name =~ /o0000/i)) && (!($file_name =~ /\/sources\//i))); # Skip other then resource and source files |
|
461 push @find_files, $file_name; |
|
462 } |
|
463 |
|
464 sub write_what_file { |
|
465 my $out = shift; |
|
466 open( WHAT, ">>$what_output_file") or die $!; |
|
467 print WHAT "$out\n"; |
|
468 close WHAT; |
|
469 |
|
470 } |
|