Added: trunk/Source/WebCore/LocalizableStrings.pm (0 => 181170)
--- trunk/Source/WebCore/LocalizableStrings.pm (rev 0)
+++ trunk/Source/WebCore/LocalizableStrings.pm 2015-03-06 18:47:28 UTC (rev 181170)
@@ -0,0 +1,223 @@
+# Copyright (C) 2006, 2007, 2009, 2010, 2013, 2015 Apple Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+# THE POSSIBILITY OF SUCH DAMAGE.
+
+use strict;
+
+my $treatWarningsAsErrors = 0;
+
+sub setTreatWarningsAsErrors($)
+{
+ ($treatWarningsAsErrors) = @_;
+}
+
+my $sawError = 0;
+
+sub sawError()
+{
+ return $sawError;
+}
+
+sub emitError($$$)
+{
+ my ($file, $line, $message) = @_;
+ print "$file:$line: $message\n";
+ $sawError = 1;
+}
+
+sub emitWarning($$$)
+{
+ my ($file, $line, $message) = @_;
+ my $prefix = $treatWarningsAsErrors ? "" : "warning: ";
+ print "$file:$line: $prefix$message\n";
+ $sawError = 1 if $treatWarningsAsErrors;
+}
+
+# Unescapes C language hexadecimal escape sequences.
+sub unescapeHexSequence($)
+{
+ my ($originalStr) = @_;
+
+ my $escapedStr = $originalStr;
+ my $unescapedStr = "";
+
+ for (;;) {
+ if ($escapedStr =~ s-^\\x([[:xdigit:]]+)--) {
+ if (256 <= hex($1)) {
+ print "Hexadecimal escape sequence out of range: \\x$1\n";
+ return undef;
+ }
+ $unescapedStr .= pack("H*", $1);
+ } elsif ($escapedStr =~ s-^(.)--) {
+ $unescapedStr .= $1;
+ } else {
+ return $unescapedStr;
+ }
+ }
+}
+
+my $keyCollisionCount = 0;
+
+sub keyCollisionCount()
+{
+ return $keyCollisionCount;
+}
+
+my $localizedCount = 0;
+
+sub localizedCount()
+{
+ return $localizedCount;
+}
+
+my %stringByKey;
+my %commentByKey;
+my %fileByKey;
+my %lineByKey;
+
+sub HandleUIString
+{
+ my ($string, $key, $comment, $file, $line) = @_;
+
+ $localizedCount++;
+
+ my $bad = 0;
+ $string = unescapeHexSequence($string);
+ if (!defined($string)) {
+ print "$file:$line: string has an illegal hexadecimal escape sequence\n";
+ $bad = 1;
+ }
+ $key = unescapeHexSequence($key);
+ if (!defined($key)) {
+ print "$file:$line: key has an illegal hexadecimal escape sequence\n";
+ $bad = 1;
+ }
+ $comment = unescapeHexSequence($comment);
+ if (!defined($comment)) {
+ print "$file:$line: comment has an illegal hexadecimal escape sequence\n";
+ $bad = 1;
+ }
+ if (grep { $_ == 0xFFFD } unpack "U*", $string) {
+ print "$file:$line: string for translation has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
+ $bad = 1;
+ }
+ if ($string ne $key && grep { $_ == 0xFFFD } unpack "U*", $key) {
+ print "$file:$line: key has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
+ $bad = 1;
+ }
+ if (grep { $_ == 0xFFFD } unpack "U*", $comment) {
+ print "$file:$line: comment for translation has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
+ $bad = 1;
+ }
+ if ($bad) {
+ $sawError = 1;
+ return;
+ }
+
+ if ($stringByKey{$key} && $stringByKey{$key} ne $string) {
+ emitWarning($file, $line, "encountered the same key, \"$key\", twice, with different strings");
+ emitWarning($fileByKey{$key}, $lineByKey{$key}, "previous occurrence");
+ $keyCollisionCount++;
+ return;
+ }
+ if ($commentByKey{$key} && $commentByKey{$key} ne $comment) {
+ emitWarning($file, $line, "encountered the same key, \"$key\", twice, with different comments");
+ emitWarning($fileByKey{$key}, $lineByKey{$key}, "previous occurrence");
+ $keyCollisionCount++;
+ return;
+ }
+
+ $fileByKey{$key} = $file;
+ $lineByKey{$key} = $line;
+ $stringByKey{$key} = $string;
+ $commentByKey{$key} = $comment;
+}
+
+sub writeStringsFile($)
+{
+ my ($file) = @_;
+
+ my $localizedStrings = "";
+
+ for my $key (sort keys %commentByKey) {
+ $localizedStrings .= "/* $commentByKey{$key} */\n\"$key\" = \"$stringByKey{$key}\";\n\n";
+ }
+
+ # Write out the strings file as UTF-8
+ open STRINGS, ">", $file or die;
+ print STRINGS $localizedStrings;
+ close STRINGS;
+}
+
+sub verifyStringsFile($)
+{
+ my ($file) = @_;
+
+ open STRINGS, $file or die;
+
+ my $lastComment;
+ my $line;
+ my $sawError;
+
+ while (<STRINGS>) {
+ chomp;
+
+ next if (/^\s*$/);
+
+ if (/^\/\* (.*) \*\/$/) {
+ $lastComment = $1;
+ } elsif (/^"((?:[^\\]|\\[^"])*)"\s*=\s*"((?:[^\\]|\\[^"])*)";$/) #
+ {
+ my $string = delete $stringByKey{$1};
+ if (!defined $string) {
+ print "$file:$.: unused key \"$1\"\n";
+ $sawError = 1;
+ } else {
+ if (!($string eq $2)) {
+ print "$file:$.: unexpected value \"$2\" for key \"$1\"\n";
+ print "$fileByKey{$1}:$lineByKey{$1}: expected value \"$string\" defined here\n";
+ $sawError = 1;
+ }
+ if (!($lastComment eq $commentByKey{$1})) {
+ print "$file:$.: unexpected comment /* $lastComment */ for key \"$1\"\n";
+ print "$fileByKey{$1}:$lineByKey{$1}: expected comment /* $commentByKey{$1} */ defined here\n";
+ $sawError = 1;
+ }
+ }
+ } else {
+ print "$file:$.: line with unexpected format: $_\n";
+ $sawError = 1;
+ }
+ }
+
+ for my $missing (keys %stringByKey) {
+ print "$fileByKey{$missing}:$lineByKey{$missing}: missing key \"$missing\"\n";
+ $sawError = 1;
+ }
+
+ if ($sawError) {
+ print "\n$file:0: file is not up to date.\n";
+ exit 1;
+ }
+}
+
+1;
Property changes on: trunk/Source/WebCore/LocalizableStrings.pm
___________________________________________________________________
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (181169 => 181170)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2015-03-06 18:45:48 UTC (rev 181169)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2015-03-06 18:47:28 UTC (rev 181170)
@@ -1369,6 +1369,7 @@
37C238221098C84200EF9F72 /* ComplexTextControllerCoreText.mm in Sources */ = {isa = PBXBuildFile; fileRef = 37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.mm */; };
37C28A6810F659CC008C7813 /* TypesettingFeatures.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C28A6710F659CC008C7813 /* TypesettingFeatures.h */; settings = {ATTRIBUTES = (Private, ); }; };
37C61F0112095C87007A3C67 /* AtomicStringKeyedMRUCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 37C61F0012095C87007A3C67 /* AtomicStringKeyedMRUCache.h */; };
+ 37D456FD1A9A50D8003330A1 /* LocalizableStrings.pm in Copy Scripts */ = {isa = PBXBuildFile; fileRef = 37D456FB1A9A50B6003330A1 /* LocalizableStrings.pm */; };
37DDCD9413844FD50008B793 /* MIMEHeader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCD9213844FD50008B793 /* MIMEHeader.cpp */; };
37DDCD9513844FD50008B793 /* MIMEHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 37DDCD9313844FD50008B793 /* MIMEHeader.h */; };
37DDCD9E13844FFA0008B793 /* Archive.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 37DDCD9D13844FFA0008B793 /* Archive.cpp */; };
@@ -6958,6 +6959,7 @@
dstPath = PrivateHeaders/Scripts;
dstSubfolderSpec = 1;
files = (
+ 37D456FD1A9A50D8003330A1 /* LocalizableStrings.pm in Copy Scripts */,
3717D7E817ECC591003C276D /* extract-localizable-strings.pl in Copy Scripts */,
);
name = "Copy Scripts";
@@ -8461,6 +8463,7 @@
37C238201098C84200EF9F72 /* ComplexTextControllerCoreText.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ComplexTextControllerCoreText.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
37C28A6710F659CC008C7813 /* TypesettingFeatures.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TypesettingFeatures.h; sourceTree = "<group>"; };
37C61F0012095C87007A3C67 /* AtomicStringKeyedMRUCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AtomicStringKeyedMRUCache.h; sourceTree = "<group>"; };
+ 37D456FB1A9A50B6003330A1 /* LocalizableStrings.pm */ = {isa = PBXFileReference; lastKnownFileType = text.script.perl; path = LocalizableStrings.pm; sourceTree = "<group>"; };
37DDCD9213844FD50008B793 /* MIMEHeader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MIMEHeader.cpp; sourceTree = "<group>"; };
37DDCD9313844FD50008B793 /* MIMEHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIMEHeader.h; sourceTree = "<group>"; };
37DDCD9D13844FFA0008B793 /* Archive.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Archive.cpp; sourceTree = "<group>"; };
@@ -15630,6 +15633,7 @@
isa = PBXGroup;
children = (
3717D7E517ECC3A6003C276D /* extract-localizable-strings.pl */,
+ 37D456FB1A9A50B6003330A1 /* LocalizableStrings.pm */,
);
name = Scripts;
sourceTree = "<group>";
Modified: trunk/Source/WebCore/extract-localizable-strings.pl (181169 => 181170)
--- trunk/Source/WebCore/extract-localizable-strings.pl 2015-03-06 18:45:48 UTC (rev 181169)
+++ trunk/Source/WebCore/extract-localizable-strings.pl 2015-03-06 18:47:28 UTC (rev 181170)
@@ -45,11 +45,12 @@
use strict;
use File::Compare;
use File::Copy;
+use FindBin;
use Getopt::Long;
+use lib $FindBin::Bin;
+use LocalizableStrings;
no warnings 'deprecated';
-sub UnescapeHexSequence($);
-
my %isDebugMacro = ( ASSERT_WITH_MESSAGE => 1, LOG_ERROR => 1, ERROR => 1, NSURL_ERROR => 1, FATAL => 1, LOG => 1, LOG_WARNING => 1, UI_STRING_LOCALIZE_LATER => 1, UI_STRING_LOCALIZE_LATER_KEY => 1, LPCTSTR_UI_STRING_LOCALIZE_LATER => 1, UNLOCALIZED_STRING => 1, UNLOCALIZED_LPCTSTR => 1, dprintf => 1, NSException => 1, NSLog => 1, printf => 1 );
my $verify;
@@ -66,6 +67,8 @@
GetOptions(%options);
+setTreatWarningsAsErrors($treatWarningsAsErrors);
+
@ARGV >= 2 or die "Usage: extract-localizable-strings [--verify] [--treat-warnings-as-errors] [--exceptions <exceptions file>] <file to update> [--skip directory | directory]...\nDid you mean to run update-webkit-localizable-strings instead?\n";
-f $exceptionsFile or die "Couldn't find exceptions file $exceptionsFile\n" unless !defined $exceptionsFile;
@@ -84,24 +87,12 @@
}
}
-my $sawError = 0;
-
-my $localizedCount = 0;
-my $keyCollisionCount = 0;
my $notLocalizedCount = 0;
my $NSLocalizeCount = 0;
my %exception;
my %usedException;
-sub emitWarning($$$)
-{
- my ($file, $line, $message) = @_;
- my $prefix = $treatWarningsAsErrors ? "" : "warning: ";
- print "$file:$line: $prefix$message\n";
- $sawError = 1 if $treatWarningsAsErrors;
-}
-
if (defined $exceptionsFile && open EXCEPTIONS, $exceptionsFile) {
while (<EXCEPTIONS>) {
chomp;
@@ -165,8 +156,7 @@
if ($token eq "\"") {
if ($expected and $expected ne "a quoted string") {
- print "$file:$.: found a quoted string but expected $expected\n";
- $sawError = 1;
+ emitError($file, $., "found a quoted string but expected $expected");
$expected = "";
}
if (s-^(([^\\$token]|\\.)*?)$token--) {
@@ -177,8 +167,7 @@
$string .= $1;
}
} else {
- print "$file:$.: mismatched quotes\n";
- $sawError = 1;
+ emitError($file, $., "mismatched quotes");
$_ = "";
}
next;
@@ -227,9 +216,8 @@
$previousToken = $token;
if ($token =~ /^NSLocalized/ && $token !~ /NSLocalizedDescriptionKey/ && $token !~ /NSLocalizedStringFromTableInBundle/ && $token !~ /NSLocalizedFileSizeDescription/ && $token !~ /NSLocalizedDescriptionKey/ && $token !~ /NSLocalizedRecoverySuggestionErrorKey/) {
- print "$file:$.: found a use of an NSLocalized macro ($token); not supported\n";
+ emitError($file, $., "found a use of an NSLocalized macro ($token); not supported");
$nestingLevel = 0 if !defined $nestingLevel;
- $sawError = 1;
$NSLocalizeCount++;
} elsif ($token eq "/*") {
if (!s-^.*?\*/--) {
@@ -240,14 +228,12 @@
$_ = ""; # Discard the rest of the line
} elsif ($token eq "'") {
if (!s-([^\\]|\\.)'--) { #' <-- that single quote makes the Project Builder editor less confused
- print "$file:$.: mismatched single quote\n";
- $sawError = 1;
+ emitError($file, $., "mismatched single quote");
$_ = "";
}
} else {
if ($expected and $expected ne $token) {
- print "$file:$.: found $token but expected $expected\n";
- $sawError = 1;
+ emitError($file, $., "found $token but expected $expected");
$expected = "";
}
if ($token =~ /(WEB_)?UI_STRING(_KEY)?(_INTERNAL)?$/) {
@@ -269,7 +255,6 @@
HandleUIString($UIString, $key, $comment, $file, $macroLine);
$macro = "";
$expected = "";
- $localizedCount++;
}
} elsif ($isDebugMacro{$token}) {
$nestingLevel = 0 if !defined $nestingLevel;
@@ -282,99 +267,14 @@
goto handleString if defined $string;
if ($expected) {
- print "$file: reached end of file but expected $expected\n";
- $sawError = 1;
+ emitError($file, 0, "reached end of file but expected $expected");
}
close SOURCE;
}
-# Unescapes C language hexadecimal escape sequences.
-sub UnescapeHexSequence($)
-{
- my ($originalStr) = @_;
+print "\n" if sawError() || $notLocalizedCount || $NSLocalizeCount;
- my $escapedStr = $originalStr;
- my $unescapedStr = "";
-
- for (;;) {
- if ($escapedStr =~ s-^\\x([[:xdigit:]]+)--) {
- if (256 <= hex($1)) {
- print "Hexadecimal escape sequence out of range: \\x$1\n";
- return undef;
- }
- $unescapedStr .= pack("H*", $1);
- } elsif ($escapedStr =~ s-^(.)--) {
- $unescapedStr .= $1;
- } else {
- return $unescapedStr;
- }
- }
-}
-
-my %stringByKey;
-my %commentByKey;
-my %fileByKey;
-my %lineByKey;
-
-sub HandleUIString
-{
- my ($string, $key, $comment, $file, $line) = @_;
-
- my $bad = 0;
- $string = UnescapeHexSequence($string);
- if (!defined($string)) {
- print "$file:$line: string has an illegal hexadecimal escape sequence\n";
- $bad = 1;
- }
- $key = UnescapeHexSequence($key);
- if (!defined($key)) {
- print "$file:$line: key has an illegal hexadecimal escape sequence\n";
- $bad = 1;
- }
- $comment = UnescapeHexSequence($comment);
- if (!defined($comment)) {
- print "$file:$line: comment has an illegal hexadecimal escape sequence\n";
- $bad = 1;
- }
- if (grep { $_ == 0xFFFD } unpack "U*", $string) {
- print "$file:$line: string for translation has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
- $bad = 1;
- }
- if ($string ne $key && grep { $_ == 0xFFFD } unpack "U*", $key) {
- print "$file:$line: key has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
- $bad = 1;
- }
- if (grep { $_ == 0xFFFD } unpack "U*", $comment) {
- print "$file:$line: comment for translation has illegal UTF-8 -- most likely a problem with the Text Encoding of the source file\n";
- $bad = 1;
- }
- if ($bad) {
- $sawError = 1;
- return;
- }
-
- if ($stringByKey{$key} && $stringByKey{$key} ne $string) {
- emitWarning($file, $line, "encountered the same key, \"$key\", twice, with different strings");
- emitWarning($fileByKey{$key}, $lineByKey{$key}, "previous occurrence");
- $keyCollisionCount++;
- return;
- }
- if ($commentByKey{$key} && $commentByKey{$key} ne $comment) {
- emitWarning($file, $line, "encountered the same key, \"$key\", twice, with different comments");
- emitWarning($fileByKey{$key}, $lineByKey{$key}, "previous occurrence");
- $keyCollisionCount++;
- return;
- }
-
- $fileByKey{$key} = $file;
- $lineByKey{$key} = $line;
- $stringByKey{$key} = $string;
- $commentByKey{$key} = $comment;
-}
-
-print "\n" if $sawError || $notLocalizedCount || $NSLocalizeCount;
-
my @unusedExceptions = sort grep { !$usedException{$_} } keys %exception;
if (@unusedExceptions) {
for my $unused (@unusedExceptions) {
@@ -383,30 +283,21 @@
print "\n";
}
-print "$localizedCount localizable strings\n" if $localizedCount;
-print "$keyCollisionCount key collisions\n" if $keyCollisionCount;
+print localizedCount() . " localizable strings\n" if localizedCount();
+print keyCollisionCount() . " key collisions\n" if keyCollisionCount();
print "$notLocalizedCount strings not marked for localization\n" if $notLocalizedCount;
print "$NSLocalizeCount uses of NSLocalize\n" if $NSLocalizeCount;
print scalar(@unusedExceptions), " unused exceptions\n" if @unusedExceptions;
-if ($sawError) {
+if (sawError()) {
print "\nErrors encountered. Exiting without writing to $fileToUpdate.\n";
exit 1;
}
-my $localizedStrings = "";
-
-for my $key (sort keys %commentByKey) {
- $localizedStrings .= "/* $commentByKey{$key} */\n\"$key\" = \"$stringByKey{$key}\";\n\n";
-}
-
if (-e "$fileToUpdate") {
if (!$verify) {
- # Write out the strings file as UTF-8
my $temporaryFile = "$fileToUpdate.updated";
- open STRINGS, ">", $temporaryFile or die;
- print STRINGS $localizedStrings;
- close STRINGS;
+ writeStringsFile($temporaryFile);
# Avoid updating the target file's modification time if the contents have not changed.
if (compare($temporaryFile, $fileToUpdate)) {
@@ -415,51 +306,7 @@
unlink $temporaryFile;
}
} else {
- open STRINGS, $fileToUpdate or die;
-
- my $lastComment;
- my $line;
-
- while (<STRINGS>) {
- chomp;
-
- next if (/^\s*$/);
-
- if (/^\/\* (.*) \*\/$/) {
- $lastComment = $1;
- } elsif (/^"((?:[^\\]|\\[^"])*)"\s*=\s*"((?:[^\\]|\\[^"])*)";$/) #
- {
- my $string = delete $stringByKey{$1};
- if (!defined $string) {
- print "$fileToUpdate:$.: unused key \"$1\"\n";
- $sawError = 1;
- } else {
- if (!($string eq $2)) {
- print "$fileToUpdate:$.: unexpected value \"$2\" for key \"$1\"\n";
- print "$fileByKey{$1}:$lineByKey{$1}: expected value \"$string\" defined here\n";
- $sawError = 1;
- }
- if (!($lastComment eq $commentByKey{$1})) {
- print "$fileToUpdate:$.: unexpected comment /* $lastComment */ for key \"$1\"\n";
- print "$fileByKey{$1}:$lineByKey{$1}: expected comment /* $commentByKey{$1} */ defined here\n";
- $sawError = 1;
- }
- }
- } else {
- print "$fileToUpdate:$.: line with unexpected format: $_\n";
- $sawError = 1;
- }
- }
-
- for my $missing (keys %stringByKey) {
- print "$fileByKey{$missing}:$lineByKey{$missing}: missing key \"$missing\"\n";
- $sawError = 1;
- }
-
- if ($sawError) {
- print "\n$fileToUpdate:0: file is not up to date.\n";
- exit 1;
- }
+ verifyStringsFile($fileToUpdate);
}
} else {
print "error: $fileToUpdate does not exist\n";