~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Tools/Scripts/check-inspector-strings

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
#
 
3
# Copyright (C) 2011 Google Inc. All rights reserved.
 
4
#
 
5
# Redistribution and use in source and binary forms, with or without
 
6
# modification, are permitted provided that the following conditions are
 
7
# met:
 
8
#
 
9
#    * Redistributions of source code must retain the above copyright
 
10
# notice, this list of conditions and the following disclaimer.
 
11
#    * Redistributions in binary form must reproduce the above
 
12
# copyright notice, this list of conditions and the following disclaimer
 
13
# in the documentation and/or other materials provided with the
 
14
# distribution.
 
15
#    * Neither the name of Google Inc. nor the names of its
 
16
# contributors may be used to endorse or promote products derived from
 
17
# this software without specific prior written permission.
 
18
#
 
19
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
20
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
21
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
22
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 
23
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
24
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 
25
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
26
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
27
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
28
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
29
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
30
 
 
31
import codecs
 
32
import logging
 
33
import os
 
34
import os.path
 
35
import re
 
36
import sys
 
37
 
 
38
from webkitpy.common.checkout.scm import SCMDetector
 
39
from webkitpy.common.system.filesystem import FileSystem
 
40
from webkitpy.common.system.executive import Executive
 
41
from webkitpy.common.system.logutils import configure_logging
 
42
from webkitpy.style.checker import ProcessorBase
 
43
from webkitpy.style.filereader import TextFileReader
 
44
from webkitpy.style.main import change_directory
 
45
 
 
46
_inspector_directory = "Source/WebCore/inspector/front-end"
 
47
_devtools_directory = "Source/WebKit/chromium/src/js"
 
48
_localized_strings = "Source/WebCore/English.lproj/localizedStrings.js"
 
49
 
 
50
_log = logging.getLogger("check-inspector-strings")
 
51
 
 
52
class StringsExtractor(ProcessorBase):
 
53
    def __init__(self, patterns):
 
54
        self._patterns = patterns
 
55
        self.strings = []
 
56
        for p in self._patterns:
 
57
            self.strings.append([])
 
58
 
 
59
    def should_process(self, file_path):
 
60
        return file_path.endswith(".js") and (not file_path.endswith("InjectedScript.js"))
 
61
 
 
62
    def process(self, lines, file_path, line_numbers=None):
 
63
        for line in lines:
 
64
            comment_start = line.find("//")
 
65
            if comment_start != -1:
 
66
                line = line[:comment_start]
 
67
            index = 0
 
68
            for pattern in self._patterns:
 
69
                line_strings = re.findall(pattern, line)
 
70
                for string in line_strings:
 
71
                    self.strings[index].append(string)
 
72
                index += 1
 
73
 
 
74
class LocalizedStringsExtractor:
 
75
    def __init__(self):
 
76
        self.localized_strings = []
 
77
 
 
78
    def process_file(self, file_path):
 
79
        localized_strings_file = codecs.open(file_path, encoding="utf-8", mode="r")
 
80
        try:
 
81
            contents = localized_strings_file.read()
 
82
            lines = contents.split("\n")
 
83
            for line in lines:
 
84
                match = re.match(r"localizedStrings\[\"((?:[^\"\\]|\\.)*?)\"", line)
 
85
                if match:
 
86
                    self.localized_strings.append(match.group(1))
 
87
        finally:
 
88
            localized_strings_file.close()
 
89
 
 
90
def extract_ui_strings(str, out):
 
91
    line_unrecognized = False
 
92
    idx = 0
 
93
    while idx < len(str):
 
94
        idx = str.find("WebInspector.UIString(", idx)
 
95
        if idx == -1:
 
96
            break
 
97
        idx = idx + len("WebInspector.UIString(")
 
98
        balance = 1
 
99
        item_recognized = False
 
100
        while idx < len(str):
 
101
            if str[idx] == ')':
 
102
                balance = balance - 1
 
103
                if balance == 0:
 
104
                    break
 
105
            elif str[idx] == '(':
 
106
                balance = balance + 1
 
107
            elif balance == 1:
 
108
                if str[idx] == ',':
 
109
                    break
 
110
                elif str[idx] == '"':
 
111
                    str_idx = idx + 1
 
112
                    while str_idx < len(str):
 
113
                        if str[str_idx] == '\\':
 
114
                            str_idx = str_idx + 1
 
115
                        elif str[str_idx] == '"':
 
116
                            out.add(str[idx + 1 : str_idx])
 
117
                            idx = str_idx
 
118
                            item_recognized = True
 
119
                            break
 
120
                        str_idx = str_idx + 1
 
121
            idx = idx + 1
 
122
        if not item_recognized:
 
123
            line_unrecognized = True
 
124
    if line_unrecognized:
 
125
        _log.info("Unrecognized: %s" % str)
 
126
 
 
127
if __name__ == "__main__":
 
128
    configure_logging()
 
129
 
 
130
    cwd = os.path.abspath(os.curdir)
 
131
    filesystem = FileSystem()
 
132
    scm = SCMDetector(filesystem, Executive()).detect_scm_system(cwd)
 
133
 
 
134
    if scm is None:
 
135
        _log.error("WebKit checkout not found: You must run this script "
 
136
                   "from within a WebKit checkout.")
 
137
        sys.exit(1)
 
138
 
 
139
    checkout_root = scm.checkout_root
 
140
    _log.debug("WebKit checkout found with root: %s" % checkout_root)
 
141
    change_directory(filesystem, checkout_root=checkout_root, paths=None)
 
142
 
 
143
    strings_extractor = StringsExtractor([r"(WebInspector\.UIString\(.*)", r"\"((?:[^\"\\]|\\.)*?)\""])
 
144
    file_reader = TextFileReader(filesystem, strings_extractor)
 
145
    file_reader.process_paths([_inspector_directory, _devtools_directory])
 
146
    localized_strings_extractor = LocalizedStringsExtractor()
 
147
    localized_strings_extractor.process_file(_localized_strings)
 
148
    raw_ui_strings = frozenset(strings_extractor.strings[0])
 
149
    ui_strings = set()
 
150
    for s in raw_ui_strings:
 
151
        extract_ui_strings(s, ui_strings)
 
152
    strings = frozenset(strings_extractor.strings[1])
 
153
    localized_strings = frozenset(localized_strings_extractor.localized_strings)
 
154
 
 
155
    new_strings = ui_strings - localized_strings
 
156
    for s in new_strings:
 
157
        _log.info("New: \"%s\"" % (s))
 
158
    old_strings = localized_strings - ui_strings
 
159
    suspicious_strings = strings & old_strings
 
160
    for s in suspicious_strings:
 
161
        _log.info("Suspicious: \"%s\"" % (s))
 
162
    unused_strings = old_strings - strings
 
163
    for s in unused_strings:
 
164
        _log.info("Unused: \"%s\"" % (s))
 
165
 
 
166
    localized_strings_duplicates = {}
 
167
    for s in localized_strings_extractor.localized_strings:
 
168
        if s in localized_strings_duplicates:
 
169
            _log.info("Duplicate: \"%s\"" % (s))
 
170
        else:
 
171
            localized_strings_duplicates.setdefault(s)