File indexing completed on 2024-05-05 04:01:50
0001 #!/usr/bin/env python3 0002 # SPDX-FileCopyrightText: 2023 Jonathan Poelen <jonathan.poelen@gmail.com> 0003 # SPDX-License-Identifier: MIT 0004 0005 from typing import Iterable, Mapping 0006 from xml.etree.ElementTree import ElementTree 0007 0008 import sys 0009 0010 if len(sys.argv) < 2: 0011 print(sys.argv[0], 'syntax.xml...', file=sys.stderr) 0012 exit(1) 0013 0014 0015 def normalize_bool_or_remove_if_false(d: dict[str, str], key: str) -> None: 0016 value = d.get(key) 0017 if value is not None: 0018 if value == '1' or value.lower() == 'true': 0019 d[key] = '1' 0020 else: 0021 d.pop(key) 0022 0023 def remove_if_stay(d: dict[str, str], key: str) -> None: 0024 value = d.get(key) 0025 if value is not None and (not value or value == '#stay'): 0026 d.pop(key) 0027 0028 0029 for filename in sys.argv[1:]: 0030 tree = ElementTree() 0031 tree.parse(filename) 0032 0033 identical_contexts = {} 0034 0035 for context in tree.getroot()[0].find("contexts"): 0036 if len(context) == 0 or (len(context) == 1 and context[0].tag == 'IncludeRules'): 0037 attrib = context.attrib 0038 name = attrib.pop('name') 0039 remove_if_stay(attrib, 'lineEndContext') 0040 remove_if_stay(attrib, 'lineEmptyContext') 0041 remove_if_stay(attrib, 'fallthroughContext') 0042 if len(context): 0043 attrib.update(context[0].attrib) 0044 normalize_bool_or_remove_if_false(attrib, 'includeAttrib') 0045 0046 s = '\n'.join(sorted(f'{k}={v}' for k,v in attrib.items())) 0047 identical_contexts.setdefault(s, []).append(name) 0048 else: 0049 rules = set() 0050 for rule in context: 0051 attrib = rule.attrib 0052 remove_if_stay(attrib, 'context') 0053 normalize_bool_or_remove_if_false(attrib, 'dynamic') 0054 normalize_bool_or_remove_if_false(attrib, 'minimal') 0055 normalize_bool_or_remove_if_false(attrib, 'includeAttrib') 0056 normalize_bool_or_remove_if_false(attrib, 'firstNonSpace') 0057 normalize_bool_or_remove_if_false(attrib, 'lookAhead') 0058 s = '\n'.join(f'{k}={v}' for k,v in sorted(attrib.items())) 0059 rules.add(f'{rule.tag}\n{s}') 0060 0061 identical_contexts.setdefault('\n'.join(sorted(rules)), []).append(context.attrib['name']) 0062 0063 for names in identical_contexts.values(): 0064 if len(names) > 1: 0065 print(f'{filename}: {names}')