Lines 13-18
using gettext-compatible translation files
Link Here
|
13 |
|
13 |
|
14 |
use strict; |
14 |
use strict; |
15 |
#use warnings; FIXME - Bug 2505 |
15 |
#use warnings; FIXME - Bug 2505 |
|
|
16 |
use File::Basename; |
16 |
use Getopt::Long; |
17 |
use Getopt::Long; |
17 |
use Locale::PO; |
18 |
use Locale::PO; |
18 |
use File::Temp qw( :POSIX ); |
19 |
use File::Temp qw( :POSIX ); |
Lines 21-27
use VerboseWarnings qw( :warn :die );
Link Here
|
21 |
|
22 |
|
22 |
############################################################################### |
23 |
############################################################################### |
23 |
|
24 |
|
24 |
use vars qw( @in_files $in_dir $str_file $out_dir $quiet ); |
25 |
use vars qw( $in_dir @filenames $str_file $out_dir $quiet ); |
25 |
use vars qw( @excludes $exclude_regex ); |
26 |
use vars qw( @excludes $exclude_regex ); |
26 |
use vars qw( $recursive_p ); |
27 |
use vars qw( $recursive_p ); |
27 |
use vars qw( $pedantic_p ); |
28 |
use vars qw( $pedantic_p ); |
Lines 131-155
sub text_replace (**) {
Link Here
|
131 |
} |
132 |
} |
132 |
} |
133 |
} |
133 |
|
134 |
|
134 |
sub listfiles ($$$) { |
135 |
sub listfiles { |
135 |
my($dir, $type, $action) = @_; |
136 |
my($dir, $type, $action, $filenames) = @_; |
136 |
my @it = (); |
137 |
my @it = (); |
137 |
if (opendir(DIR, $dir)) { |
138 |
if (opendir(DIR, $dir)) { |
138 |
my @dirent = readdir DIR; # because DIR is shared when recursing |
139 |
my @dirent = readdir DIR; # because DIR is shared when recursing |
139 |
closedir DIR; |
140 |
closedir DIR; |
140 |
for my $dirent (@dirent) { |
141 |
for my $dirent (@dirent) { |
141 |
my $path = "$dir/$dirent"; |
142 |
my $path = "$dir/$dirent"; |
142 |
if ($dirent =~ /^\./ || $dirent eq 'CVS' || $dirent eq 'RCS' |
143 |
if ($dirent =~ /^\./ || $dirent eq 'CVS' || $dirent eq 'RCS' |
143 |
|| (defined $exclude_regex && $dirent =~ /^(?:$exclude_regex)$/)) { |
144 |
|| (defined $exclude_regex && $dirent =~ /^(?:$exclude_regex)$/)) { |
144 |
; |
145 |
; |
145 |
} elsif (-f $path) { |
146 |
} elsif (-f $path) { |
146 |
push @it, $path if (!defined $type || $dirent =~ /\.(?:$type)$/) || $action eq 'install'; |
147 |
my $basename = basename $path; |
147 |
} elsif (-d $path && $recursive_p) { |
148 |
push @it, $path |
148 |
push @it, listfiles($path, $type, $action); |
149 |
if ( not @$filenames or ( grep { $basename =~ /$_/ } @$filenames ) ) |
|
|
150 |
and (!defined $type || $dirent =~ /\.(?:$type)$/) || $action eq 'install'; |
151 |
} elsif (-d $path && $recursive_p) { |
152 |
push @it, listfiles($path, $type, $action, $filenames); |
153 |
} |
149 |
} |
154 |
} |
150 |
} |
|
|
151 |
} else { |
155 |
} else { |
152 |
warn_normal "$dir: $!", undef; |
156 |
warn_normal "$dir: $!", undef; |
153 |
} |
157 |
} |
154 |
return @it; |
158 |
return @it; |
155 |
} |
159 |
} |
Lines 181-192
Usage: $0 create [OPTION]
Link Here
|
181 |
or: $0 --help |
185 |
or: $0 --help |
182 |
Create or update PO files from templates, or install translated templates. |
186 |
Create or update PO files from templates, or install translated templates. |
183 |
|
187 |
|
184 |
-i, --input=SOURCE Get or update strings from SOURCE file. |
188 |
-i, --input=SOURCE Get or update strings from SOURCE directory. |
185 |
SOURCE is a directory if -r is also specified. |
|
|
186 |
-o, --outputdir=DIRECTORY Install translation(s) to specified DIRECTORY |
189 |
-o, --outputdir=DIRECTORY Install translation(s) to specified DIRECTORY |
187 |
--pedantic-warnings Issue warnings even for detected problems |
190 |
--pedantic-warnings Issue warnings even for detected problems |
188 |
which are likely to be harmless |
191 |
which are likely to be harmless |
189 |
-r, --recursive SOURCE in the -i option is a directory |
192 |
-r, --recursive SOURCE in the -i option is a directory |
|
|
193 |
-f, --filename=FILE FILE is a specific filaneme. |
194 |
If given, only these files will be processed. |
190 |
-s, --str-file=FILE Specify FILE as the translation (po) file |
195 |
-s, --str-file=FILE Specify FILE as the translation (po) file |
191 |
for input (install) or output (create, update) |
196 |
for input (install) or output (create, update) |
192 |
-x, --exclude=REGEXP Exclude files matching the given REGEXP |
197 |
-x, --exclude=REGEXP Exclude files matching the given REGEXP |
Lines 212-218
sub usage_error (;$) {
Link Here
|
212 |
############################################################################### |
217 |
############################################################################### |
213 |
|
218 |
|
214 |
GetOptions( |
219 |
GetOptions( |
215 |
'input|i=s' => \@in_files, |
220 |
'input|i=s' => \$in_dir, |
|
|
221 |
'filename|f=s' => \@filenames, |
216 |
'outputdir|o=s' => \$out_dir, |
222 |
'outputdir|o=s' => \$out_dir, |
217 |
'recursive|r' => \$recursive_p, |
223 |
'recursive|r' => \$recursive_p, |
218 |
'str-file|s=s' => \$str_file, |
224 |
'str-file|s=s' => \$str_file, |
Lines 233-268
$SIG{__WARN__} = sub {
Link Here
|
233 |
|
239 |
|
234 |
my $action = shift or usage_error('You must specify an ACTION.'); |
240 |
my $action = shift or usage_error('You must specify an ACTION.'); |
235 |
usage_error('You must at least specify input and string list filenames.') |
241 |
usage_error('You must at least specify input and string list filenames.') |
236 |
if !@in_files || !defined $str_file; |
242 |
if !$in_dir || !defined $str_file; |
237 |
|
243 |
|
238 |
# Type match defaults to *.tt plus *.inc if not specified |
244 |
# Type match defaults to *.tt plus *.inc if not specified |
239 |
$type = "tt|inc|xsl|xml" if !defined($type); |
245 |
$type = "tt|inc|xsl|xml" if !defined($type); |
240 |
|
246 |
|
241 |
# Check the inputs for being files or directories |
247 |
# Check the inputs for being directories |
242 |
for my $input (@in_files) { |
248 |
usage_error("$in_dir: Input must be a directory.\n" |
243 |
usage_error("$input: Input must be a file or directory.\n" |
249 |
. "(Symbolic links are not supported at the moment)") |
244 |
. "(Symbolic links are not supported at the moment)") |
250 |
unless -d $in_dir; |
245 |
unless -d $input || -f $input;; |
|
|
246 |
} |
247 |
|
251 |
|
248 |
# Generates the global exclude regular expression |
252 |
# Generates the global exclude regular expression |
249 |
$exclude_regex = '(?:'.join('|', @excludes).')' if @excludes; |
253 |
$exclude_regex = '(?:'.join('|', @excludes).')' if @excludes; |
250 |
|
254 |
|
|
|
255 |
my @in_files; |
251 |
# Generate the list of input files if a directory is specified |
256 |
# Generate the list of input files if a directory is specified |
252 |
if (-d $in_files[0]) { |
257 |
# input is a directory, generates list of files to process |
253 |
die "If you specify a directory as input, you must specify only it.\n" |
258 |
$in_dir =~ s/\/$//; # strips the trailing / if any |
254 |
if @in_files > 1; |
259 |
|
255 |
|
260 |
for my $fn ( @filenames ) { |
256 |
# input is a directory, generates list of files to process |
|
|
257 |
$in_dir = $in_files[0]; |
258 |
$in_dir =~ s/\/$//; # strips the trailing / if any |
259 |
@in_files = listfiles($in_dir, $type, $action); |
260 |
} else { |
261 |
for my $input (@in_files) { |
262 |
die "You cannot specify input files and directories at the same time.\n" |
261 |
die "You cannot specify input files and directories at the same time.\n" |
263 |
unless -f $input; |
262 |
if -d $fn; |
264 |
} |
|
|
265 |
} |
263 |
} |
|
|
264 |
@in_files = listfiles($in_dir, $type, $action, \@filenames); |
266 |
|
265 |
|
267 |
# restores the string list from file |
266 |
# restores the string list from file |
268 |
$href = Locale::PO->load_file_ashash($str_file); |
267 |
$href = Locale::PO->load_file_ashash($str_file); |
Lines 405-427
if ($action eq 'create') {
Link Here
|
405 |
for my $input (@in_files) { |
404 |
for my $input (@in_files) { |
406 |
die "Assertion failed" |
405 |
die "Assertion failed" |
407 |
unless substr($input, 0, length($in_dir) + 1) eq "$in_dir/"; |
406 |
unless substr($input, 0, length($in_dir) + 1) eq "$in_dir/"; |
408 |
# print "$input / $type\n"; |
407 |
|
|
|
408 |
my $target = $out_dir . substr($input, length($in_dir)); |
409 |
my $targetdir = $` if $target =~ /[^\/]+$/s; |
410 |
|
409 |
if (!defined $type || $input =~ /\.(?:$type)$/) { |
411 |
if (!defined $type || $input =~ /\.(?:$type)$/) { |
410 |
my $h = TmplTokenizer->new( $input ); |
412 |
my $h = TmplTokenizer->new( $input ); |
411 |
$h->set_allow_cformat( 1 ); |
413 |
$h->set_allow_cformat( 1 ); |
412 |
VerboseWarnings::set_input_file_name $input; |
414 |
VerboseWarnings::set_input_file_name $input; |
413 |
|
|
|
414 |
my $target = $out_dir . substr($input, length($in_dir)); |
415 |
my $targetdir = $` if $target =~ /[^\/]+$/s; |
416 |
mkdir_recursive($targetdir) unless -d $targetdir; |
415 |
mkdir_recursive($targetdir) unless -d $targetdir; |
417 |
print STDERR "Creating $target...\n" unless $quiet; |
416 |
print STDERR "Creating $target...\n" unless $quiet; |
418 |
open( OUTPUT, ">$target" ) || die "$target: $!\n"; |
417 |
open( OUTPUT, ">$target" ) || die "$target: $!\n"; |
419 |
text_replace( $h, *OUTPUT ); |
418 |
text_replace( $h, *OUTPUT ); |
420 |
close OUTPUT; |
419 |
close OUTPUT; |
421 |
} else { |
420 |
} else { |
422 |
# just copying the file |
421 |
# just copying the file |
423 |
my $target = $out_dir . substr($input, length($in_dir)); |
|
|
424 |
my $targetdir = $` if $target =~ /[^\/]+$/s; |
425 |
mkdir_recursive($targetdir) unless -d $targetdir; |
422 |
mkdir_recursive($targetdir) unless -d $targetdir; |
426 |
system("cp -f $input $target"); |
423 |
system("cp -f $input $target"); |
427 |
print STDERR "Copying $input...\n" unless $quiet; |
424 |
print STDERR "Copying $input...\n" unless $quiet; |