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