summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xitstool.in105
1 files changed, 74 insertions, 31 deletions
diff --git a/itstool.in b/itstool.in
index e64cd34..c21ad4b 100755
--- a/itstool.in
+++ b/itstool.in
@@ -554,6 +554,8 @@ class Document (object):
self._itst_credits = None
self._its_externals = {}
+ self._clear_cache()
+
def __del__ (self):
self._doc.freeDoc()
@@ -561,17 +563,27 @@ class Document (object):
if self._xml_err:
raise libxml2.parserError(self._xml_err)
- def register_its_params(self, xpath, rules, params={}):
+ def _clear_cache(self):
+ self._its_translate_nodes_cache = {}
+ self._its_locale_filters_cache = {}
+ self._its_loc_notes_cache = {}
+
+ def get_its_params(self, rules):
+ params = {}
for child in xml_child_iter(rules):
if xml_is_ns_name(child, NS_ITS, 'param'):
- name = child.nsProp('name', None)
- if name in params:
- value = params[name]
- else:
- value = child.getContent()
- xpath.xpathRegisterVariable(name, None, value)
+ params[child.nsProp('name', None)] = child.getContent()
+ return params
+
+ def register_its_params(self, xpath, params, userparams={}):
+ for param in params:
+ if param in userparams:
+ xpath.xpathRegisterVariable(name, None, userparams[param])
+ else:
+ xpath.xpathRegisterVariable(name, None, params[param])
def apply_its_rule(self, rule, xpath):
+ self._clear_cache()
if rule.type != 'element':
return
if xml_is_ns_name(rule, NS_ITS, 'translateRule'):
@@ -733,7 +745,8 @@ class Document (object):
self._its_externals[node] = res[0].content
xpath.setContextNode(oldnode)
- def apply_its_rules(self, builtins, params={}):
+ def apply_its_rules(self, builtins, userparams={}):
+ self._clear_cache()
if builtins:
dirs = []
ddir = os.getenv('XDG_DATA_HOME', '')
@@ -754,11 +767,12 @@ class Document (object):
for dfile in os.listdir(itsdir):
if dfile.endswith('.its'):
if not ddone.get(dfile, False):
- self.apply_its_file(os.path.join(itsdir, dfile), params=params)
+ self.apply_its_file(os.path.join(itsdir, dfile), userparams=userparams)
ddone[dfile] = True
- self.apply_local_its_rules(params=params)
+ self.apply_local_its_rules(userparams=userparams)
- def apply_its_file(self, filename, params={}):
+ def apply_its_file(self, filename, userparams={}):
+ self._clear_cache()
doc = libxml2.parseFile(filename)
root = doc.getRootElement()
if not xml_is_ns_name(root, NS_ITS, 'rules'):
@@ -795,6 +809,7 @@ class Document (object):
break
if matched == False:
return
+ params = self.get_its_params(root)
for rule in xml_child_iter(root):
xpath = self._doc.xpathNewContext()
par = match
@@ -808,10 +823,11 @@ class Document (object):
xpath.xpathRegisterNs(nsdef.name, nsdef.content)
nsdef = nsdef.next
par = par.parent
- self.register_its_params(xpath, root, params=params)
+ self.register_its_params(xpath, params, userparams=userparams)
self.apply_its_rule(rule, xpath)
- def apply_local_its_rules(self, params={}):
+ def apply_local_its_rules(self, userparams={}):
+ self._clear_cache()
for rules in self._localrules:
def reg_ns(xpath, node):
if node.parent is not None:
@@ -823,14 +839,15 @@ class Document (object):
nsdef = nsdef.next
xpath = self._doc.xpathNewContext()
reg_ns(xpath, rules)
- self.register_its_params(xpath, rules, params=params)
+ params = self.get_its_params(rules)
+ self.register_its_params(xpath, params, userparams=userparams)
for rule in xml_child_iter(rules):
if rule.type != 'element':
continue
if rule.nsDefs() is not None:
rule_xpath = self._doc.xpathNewContext()
reg_ns(rule_xpath, rule)
- self.register_its_params(rule_xpath, rules, params=params)
+ self.register_its_params(rule_xpath, params, userparams=userparams)
else:
rule_xpath = xpath
self.apply_its_rule(rule, rule_xpath)
@@ -1111,7 +1128,7 @@ class Document (object):
self.generate_message(child, None, comments=comments)
break
- def generate_message (self, node, msg, comments=True, path=None):
+ def generate_message(self, node, msg, comments=True, path=None):
if node.type in ('text', 'cdata') and msg is not None:
msg.add_text(node.content)
return
@@ -1261,6 +1278,8 @@ class Document (object):
return False
def get_its_translate(self, node):
+ if node in self._its_translate_nodes_cache:
+ return self._its_translate_nodes_cache[node]
val = None
if node.hasNsProp('translate', NS_ITS):
val = node.nsProp('translate', NS_ITS)
@@ -1269,11 +1288,14 @@ class Document (object):
elif node in self._its_translate_nodes:
val = self._its_translate_nodes[node]
if val is not None:
+ self._its_translate_nodes_cache[node] = val
return val
if node.type == 'attribute':
return 'no'
if node.parent.type == 'element':
- return self.get_its_translate(node.parent)
+ parval = self.get_its_translate(node.parent)
+ self._its_translate_nodes_cache[node] = parval
+ return parval
return 'yes'
def get_its_within_text(self, node):
@@ -1288,6 +1310,8 @@ class Document (object):
return 'no'
def get_its_locale_filter(self, node):
+ if node in self._its_locale_filters_cache:
+ return self._its_locale_filters_cache[node]
if node.hasNsProp('localeFilterList', NS_ITS) or node.hasNsProp('localeFilterType', NS_ITS):
if node.hasNsProp('localeFilterList', NS_ITS):
lst = node.nsProp('localeFilterList', NS_ITS)
@@ -1312,7 +1336,9 @@ class Document (object):
if node in self._its_locale_filters:
return self._its_locale_filters[node]
if node.parent.type == 'element':
- return self.get_its_locale_filter(node.parent)
+ parval = self.get_its_locale_filter(node.parent)
+ self._its_locale_filters_cache[node] = parval
+ return parval
return ('*', 'include')
def get_itst_drop(self, node):
@@ -1328,15 +1354,21 @@ class Document (object):
return self._its_id_values.get(node, None)
def get_its_loc_notes(self, node, inherit=True):
+ if node in self._its_loc_notes_cache:
+ return self._its_loc_notes_cache[node]
ret = []
- if node.hasNsProp('locNote', NS_ITS) or node.hasNsProp('locNoteRef', NS_ITS) or node.hasNsProp('locNoteType', NS_ITS):
+ if ( node.hasNsProp('locNote', NS_ITS) or
+ node.hasNsProp('locNoteRef', NS_ITS) or
+ node.hasNsProp('locNoteType', NS_ITS) ):
notetype = node.nsProp('locNoteType', NS_ITS)
if node.hasNsProp('locNote', NS_ITS):
ret.append(LocNote(locnote=node.nsProp('locNote', NS_ITS), locnotetype=notetype))
elif node.hasNsProp('locNoteRef', NS_ITS):
ret.append(LocNote(locnoteref=node.nsProp('locNoteRef', NS_ITS), locnotetype=notetype))
elif xml_is_ns_name(node, NS_ITS, 'span'):
- if node.hasNsProp('locNote', None) or node.hasNsProp('locNoteRef', None) or node.hasNsProp('locNoteType', None):
+ if ( node.hasNsProp('locNote', None) or
+ node.hasNsProp('locNoteRef', None) or
+ node.hasNsProp('locNoteType', None) ):
notetype = node.nsProp('locNoteType', None)
if node.hasNsProp('locNote', None):
ret.append(LocNote(locnote=node.nsProp('locNote', None), locnotetype=notetype))
@@ -1346,7 +1378,10 @@ class Document (object):
ret.append(locnote)
if (len(ret) == 0 and inherit and
node.type != 'attribute' and node.parent is not None and node.parent.type == 'element'):
- return self.get_its_loc_notes(node.parent)
+ parval = self.get_its_loc_notes(node.parent)
+ self._its_loc_notes_cache[node] = parval
+ return parval
+ self._its_loc_notes_cache[node] = ret
return ret
def output_test_data(self, category, out, node=None):
@@ -1460,6 +1495,7 @@ def convert_locale (locale):
return ret
+#def main():
if __name__ == '__main__':
options = optparse.OptionParser()
options.set_usage('\n itstool [OPTIONS] [XMLFILES]\n' +
@@ -1516,7 +1552,7 @@ if __name__ == '__main__':
help='Keep entity reference unexpanded')
options.add_option('-p', '--param',
action='append',
- dest='params',
+ dest='userparams',
default=[],
nargs=2,
metavar='NAME VALUE',
@@ -1537,18 +1573,18 @@ if __name__ == '__main__':
print('itstool %s' % VERSION)
sys.exit(0)
- params = {}
- for name, value in opts.params:
- params[name] = value
+ userparams = {}
+ for name, value in opts.userparams:
+ userparams[name] = value
if opts.merge is None and opts.join is None:
messages = MessageList()
for filename in args[1:]:
doc = Document(filename, messages, load_dtd=opts.load_dtd, keep_entities=opts.keep_entities)
- doc.apply_its_rules(not(opts.nobuiltins), params=params)
+ doc.apply_its_rules(not(opts.nobuiltins), userparams=userparams)
if opts.itsfile is not None:
for itsfile in opts.itsfile:
- doc.apply_its_file(itsfile, params=params)
+ doc.apply_its_file(itsfile, userparams=userparams)
if opts.test is None:
doc.generate_messages()
if opts.output is None or opts.output == '-':
@@ -1590,10 +1626,10 @@ if __name__ == '__main__':
for filename in args[1:]:
messages = MessageList()
doc = Document(filename, messages, load_dtd=opts.load_dtd, keep_entities=opts.keep_entities)
- doc.apply_its_rules(not(opts.nobuiltins), params=params)
+ doc.apply_its_rules(not(opts.nobuiltins), userparams=userparams)
if opts.itsfile is not None:
for itsfile in opts.itsfile:
- doc.apply_its_file(itsfile, params=params)
+ doc.apply_its_file(itsfile, userparams=userparams)
try:
doc.merge_translations(translations, opts.lang, strict=opts.strict)
except Exception as e:
@@ -1634,10 +1670,10 @@ if __name__ == '__main__':
out = open(opts.output, 'wb')
messages = MessageList()
doc = Document(opts.join, messages)
- doc.apply_its_rules(not(opts.nobuiltins), params=params)
+ doc.apply_its_rules(not(opts.nobuiltins), userparams=userparams)
if opts.itsfile is not None:
for itsfile in opts.itsfile:
- doc.apply_its_file(itsfile, params=params)
+ doc.apply_its_file(itsfile, userparams=userparams)
doc.join_translations(translations, strict=opts.strict)
serialized = doc._doc.serialize('utf-8')
if PY3:
@@ -1646,3 +1682,10 @@ if __name__ == '__main__':
serialized = serialized.encode('utf-8')
out.write(serialized)
out.flush()
+
+#if __name__ == '__main__':
+# if os.getenv('ITSTOOL_PROFILE') is not None:
+# import cProfile
+# cProfile.run('main()')
+# else:
+# main()