Revert "Use standard spelling for two languages"
[profile/ivi/qtbase.git] / util / local_database / xpathlite.py
1 #!/usr/bin/env python
2 #############################################################################
3 ##
4 ## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
5 ## All rights reserved.
6 ## Contact: Nokia Corporation (qt-info@nokia.com)
7 ##
8 ## This file is part of the test suite of the Qt Toolkit.
9 ##
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.
18 ##
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.
22 ##
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.
30 ##
31 ## Other Usage
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.
34 ##
35 ##
36 ##
37 ##
38 ##
39 ## $QT_END_LICENSE$
40 ##
41 #############################################################################
42
43 import sys
44 import os
45 import xml.dom.minidom
46
47 doc_cache = {}
48
49 class DraftResolution:
50     # See http://www.unicode.org/cldr/process.html for description
51     unconfirmed = 'unconfirmed'
52     provisional = 'provisional'
53     contributed = 'contributed'
54     approved = 'approved'
55     _values = { unconfirmed : 1, provisional : 2, contributed : 3, approved : 4 }
56     def __init__(self, resolution):
57         self.resolution = resolution
58     def toInt(self):
59         return DraftResolution._values[self.resolution]
60
61 class Error:
62     def __init__(self, msg):
63         self.msg = msg
64     def __str__(self):
65         return self.msg
66
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:
70             continue
71         if node.nodeName != tag_name:
72             continue
73         if arg_value:
74             if not node.attributes.has_key(arg_name):
75                 continue
76             if node.attributes[arg_name].nodeValue != arg_value:
77                 continue
78         if draft:
79             if not node.attributes.has_key('draft'):
80                 # if draft is not specified then it's approved
81                 return node
82             value = node.attributes['draft'].nodeValue
83             value = DraftResolution(value).toInt()
84             exemplar = DraftResolution(draft).toInt()
85             if exemplar > value:
86                 continue
87         return node
88     return False
89
90 def findTagsInFile(file, path):
91     doc = False
92     if doc_cache.has_key(file):
93         doc = doc_cache[file]
94     else:
95         doc = xml.dom.minidom.parse(file)
96         doc_cache[file] = doc
97
98     elt = doc.documentElement
99     tag_spec_list = path.split("/")
100     last_entry = None
101     for i in range(len(tag_spec_list)):
102         tag_spec = tag_spec_list[i]
103         tag_name = tag_spec
104         arg_name = 'type'
105         arg_value = ''
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]
113             else:
114                 arg_value = arg_value[0]
115         elt = findChild(elt, tag_name, arg_name, arg_value)
116         if not elt:
117             return None
118     ret = []
119     if elt.childNodes:
120         for node in elt.childNodes:
121             if node.attributes:
122                 element = [node.nodeName, None]
123                 element[1] = node.attributes.items()
124                 ret.append(element)
125     else:
126         if elt.attributes:
127             element = [elt.nodeName, None]
128             element[1] = elt.attributes.items()
129             ret.append(element)
130     return ret
131
132 def _findEntryInFile(file, path, draft=None, attribute=None):
133     doc = False
134     if doc_cache.has_key(file):
135         doc = doc_cache[file]
136     else:
137         doc = xml.dom.minidom.parse(file)
138         doc_cache[file] = doc
139
140     elt = doc.documentElement
141     tag_spec_list = path.split("/")
142     last_entry = None
143     for i in range(len(tag_spec_list)):
144         tag_spec = tag_spec_list[i]
145         tag_name = tag_spec
146         arg_name = 'type'
147         arg_value = ''
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]
155             else:
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("/")
161             def resolve(x, y):
162                 if y == '..':
163                     return x[:-1]
164                 return x + [y]
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)
175         if not elt:
176             return ("", None)
177     if attribute is not None:
178         if elt.attributes.has_key(attribute):
179             return (elt.attributes[attribute].nodeValue, None)
180         return (None, None)
181     return (elt.firstChild.nodeValue, None)
182
183 def findAlias(file):
184     if not doc_cache.has_key(file):
185         return False
186     doc = doc_cache[file]
187     alias_elt = findChild(doc.documentElement, "alias")
188     if not alias_elt:
189         return False
190     if not alias_elt.attributes.has_key('source'):
191         return False
192     return alias_elt.attributes['source'].nodeValue
193
194 def _findEntry(base, path, draft=None, attribute=None):
195     file = base
196     if base.endswith(".xml"):
197         filename = base
198         base = base[:-4]
199     else:
200         file = base + ".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))))
206     for item in items:
207         file = dirname + "/" + item + ".xml"
208         if os.path.isfile(file):
209             alias = findAlias(file)
210             if alias:
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)
218                 return result
219             (result, aliaspath) = _findEntryInFile(file, path, draft, attribute)
220             if aliaspath:
221                 # start lookup again because of the alias source="locale"
222                 return _findEntry(base, aliaspath, draft, attribute)
223             if result:
224                 return result
225     return None
226
227 def findEntry(base, path, draft=None, attribute=None):
228     file = base
229     if base.endswith(".xml"):
230         file = base
231         base = base[:-4]
232     else:
233         file = base + ".xml"
234     (dirname, filename) = os.path.split(base)
235
236     result = None
237     while path:
238         result = _findEntry(base, path, draft, attribute)
239         if result:
240             return result
241         (result, aliaspath) = _findEntryInFile(dirname + "/root.xml", path, draft, attribute)
242         if result:
243             return result
244         if not aliaspath:
245             raise Error("findEntry: fatal error: %s: did not found key %s" % (filename, path))
246         path = aliaspath
247
248     return result
249