2 #############################################################################
4 ## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
5 ## All rights reserved.
6 ## Contact: Nokia Corporation (qt-info@nokia.com)
8 ## This file is part of the test suite of the Qt Toolkit.
10 ## $QT_BEGIN_LICENSE:LGPL$
11 ## GNU Lesser General Public License Usage
12 ## This file may be used under the terms of the GNU Lesser General Public
13 ## License version 2.1 as published by the Free Software Foundation and
14 ## appearing in the file LICENSE.LGPL included in the packaging of this
15 ## file. Please review the following information to ensure the GNU Lesser
16 ## General Public License version 2.1 requirements will be met:
17 ## http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
19 ## In addition, as a special exception, Nokia gives you certain additional
20 ## rights. These rights are described in the Nokia Qt LGPL Exception
21 ## version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
23 ## GNU General Public License Usage
24 ## Alternatively, this file may be used under the terms of the GNU General
25 ## Public License version 3.0 as published by the Free Software Foundation
26 ## and appearing in the file LICENSE.GPL included in the packaging of this
27 ## file. Please review the following information to ensure the GNU General
28 ## Public License version 3.0 requirements will be met:
29 ## http://www.gnu.org/copyleft/gpl.html.
32 ## Alternatively, this file may be used in accordance with the terms and
33 ## conditions contained in a signed written agreement between you and Nokia.
41 #############################################################################
45 import xml.dom.minidom
49 class DraftResolution:
50 # See http://www.unicode.org/cldr/process.html for description
51 unconfirmed = 'unconfirmed'
52 provisional = 'provisional'
53 contributed = 'contributed'
55 _values = { unconfirmed : 1, provisional : 2, contributed : 3, approved : 4 }
56 def __init__(self, resolution):
57 self.resolution = resolution
59 return DraftResolution._values[self.resolution]
62 def __init__(self, msg):
67 def findChild(parent, tag_name, arg_name=None, arg_value=None, draft=None):
68 for node in parent.childNodes:
69 if node.nodeType != node.ELEMENT_NODE:
71 if node.nodeName != tag_name:
74 if not node.attributes.has_key(arg_name):
76 if node.attributes[arg_name].nodeValue != arg_value:
79 if not node.attributes.has_key('draft'):
80 # if draft is not specified then it's approved
82 value = node.attributes['draft'].nodeValue
83 value = DraftResolution(value).toInt()
84 exemplar = DraftResolution(draft).toInt()
90 def findTagsInFile(file, path):
92 if doc_cache.has_key(file):
95 doc = xml.dom.minidom.parse(file)
98 elt = doc.documentElement
99 tag_spec_list = path.split("/")
101 for i in range(len(tag_spec_list)):
102 tag_spec = tag_spec_list[i]
106 left_bracket = tag_spec.find('[')
107 if left_bracket != -1:
108 tag_name = tag_spec[:left_bracket]
109 arg_value = tag_spec[left_bracket+1:-1].split("=")
110 if len(arg_value) == 2:
111 arg_name = arg_value[0]
112 arg_value = arg_value[1]
114 arg_value = arg_value[0]
115 elt = findChild(elt, tag_name, arg_name, arg_value)
120 for node in elt.childNodes:
122 element = [node.nodeName, None]
123 element[1] = node.attributes.items()
127 element = [elt.nodeName, None]
128 element[1] = elt.attributes.items()
132 def _findEntryInFile(file, path, draft=None, attribute=None):
134 if doc_cache.has_key(file):
135 doc = doc_cache[file]
137 doc = xml.dom.minidom.parse(file)
138 doc_cache[file] = doc
140 elt = doc.documentElement
141 tag_spec_list = path.split("/")
143 for i in range(len(tag_spec_list)):
144 tag_spec = tag_spec_list[i]
148 left_bracket = tag_spec.find('[')
149 if left_bracket != -1:
150 tag_name = tag_spec[:left_bracket]
151 arg_value = tag_spec[left_bracket+1:-1].split("=")
152 if len(arg_value) == 2:
153 arg_name = arg_value[0]
154 arg_value = arg_value[1]
156 arg_value = arg_value[0]
157 alias = findChild(elt, 'alias')
158 if alias and alias.attributes['source'].nodeValue == 'locale':
159 path = alias.attributes['path'].nodeValue
160 aliaspath = tag_spec_list[:i] + path.split("/")
165 # resolve all dot-dot parts of the path
166 aliaspath = reduce(resolve, aliaspath, [])
167 # remove attribute specification that our xpathlite doesnt support
168 aliaspath = map(lambda x: x.replace("@type=", "").replace("'", ""), aliaspath)
169 # append the remaining path
170 aliaspath = aliaspath + tag_spec_list[i:]
171 aliaspath = "/".join(aliaspath)
172 # "locale" aliases are special - we need to start lookup from scratch
173 return (None, aliaspath)
174 elt = findChild(elt, tag_name, arg_name, arg_value, draft)
177 if attribute is not None:
178 if elt.attributes.has_key(attribute):
179 return (elt.attributes[attribute].nodeValue, None)
181 return (elt.firstChild.nodeValue, None)
184 if not doc_cache.has_key(file):
186 doc = doc_cache[file]
187 alias_elt = findChild(doc.documentElement, "alias")
190 if not alias_elt.attributes.has_key('source'):
192 return alias_elt.attributes['source'].nodeValue
194 def _findEntry(base, path, draft=None, attribute=None):
196 if base.endswith(".xml"):
201 (dirname, filename) = os.path.split(base)
202 items = filename.split("_")
203 # split locale name into items and iterate through them from back to front
204 # example: az_Latn_AZ => [az_Latn_AZ, az_Latn, az]
205 items = reversed(map(lambda x: "_".join(items[:x+1]), range(len(items))))
207 file = dirname + "/" + item + ".xml"
208 if os.path.isfile(file):
209 alias = findAlias(file)
211 # if alias is found we should follow it and stop processing current file
212 # see http://www.unicode.org/reports/tr35/#Common_Elements
213 aliasfile = os.path.dirname(file) + "/" + alias + ".xml"
214 if not os.path.isfile(aliasfile):
215 raise Error("findEntry: fatal error: found an alias '%s' to '%s', but the alias file couldnt be found" % (filename, alias))
216 # found an alias, recurse into parsing it
217 result = _findEntry(aliasfile, path, draft, attribute)
219 (result, aliaspath) = _findEntryInFile(file, path, draft, attribute)
221 # start lookup again because of the alias source="locale"
222 return _findEntry(base, aliaspath, draft, attribute)
227 def findEntry(base, path, draft=None, attribute=None):
229 if base.endswith(".xml"):
234 (dirname, filename) = os.path.split(base)
238 result = _findEntry(base, path, draft, attribute)
241 (result, aliaspath) = _findEntryInFile(dirname + "/root.xml", path, draft, attribute)
245 raise Error("findEntry: fatal error: %s: did not found key %s" % (filename, path))