diff options
-rwxr-xr-x | itstool.in | 105 |
1 files changed, 74 insertions, 31 deletions
@@ -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() |