6 import xml.etree.ElementTree as ET
11 DEFAULT_RULES_XML = '@XKB_CONFIG_ROOT@/rules/evdev.xml'
13 # Meson needs to fill this in so we can call the tool in the buildir.
14 EXTRA_PATH='@MESON_BUILD_ROOT@'
15 os.environ['PATH'] = ':'.join([EXTRA_PATH, os.getenv('PATH')])
18 # The function generating the progress bar (if any).
19 progress_bar = lambda x, desc: x
20 if os.isatty(sys.stdout.fileno()):
30 def xkbcommontool(r='evdev', m='pc105', l='us', v=None, o=None):
38 args += ['--variant', v]
40 args += ['--options', o]
43 print(':: {}'.format(' '.join(args)))
46 output = subprocess.check_output(args, stderr=subprocess.STDOUT)
48 print(output.decode('utf-8'))
49 except subprocess.CalledProcessError as err:
50 print('ERROR: Failed to compile: {}'.format(' '.join(args)))
51 print(err.output.decode('utf-8'))
55 def xkbcomp(r='evdev', m='pc105', l='us', v='', o=''):
56 args = ['setxkbmap', '-print']
59 args.append('{}'.format(r))
62 args.append('{}'.format(m))
64 args.append('-layout')
65 args.append('{}'.format(l))
67 args.append('-option')
68 args.append('{}'.format(o))
71 print(':: {}'.format(' '.join(args)))
74 xkbcomp_args = ['xkbcomp', '-xkb', '-', '-']
76 setxkbmap = subprocess.Popen(args, stdout=subprocess.PIPE)
77 xkbcomp = subprocess.Popen(xkbcomp_args, stdin=setxkbmap.stdout,
78 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
79 setxkbmap.stdout.close()
80 stdout, stderr = xkbcomp.communicate()
81 if xkbcomp.returncode != 0:
82 print('ERROR: Failed to compile: {}'.format(' '.join(args)))
83 if xkbcomp.returncode != 0 or verbose:
84 print(stdout.decode('utf-8'))
85 print(stderr.decode('utf-8'))
87 # This catches setxkbmap errors.
88 except subprocess.CalledProcessError as err:
89 print('ERROR: Failed to compile: {}'.format(' '.join(args)))
90 print(err.output.decode('utf-8'))
93 def parse(root, tool):
94 layouts = root.findall('layoutList/layout')
98 for e in root.findall('optionList/group/option/configItem/name')
101 for l in progress_bar(layouts, 'layout '):
102 layout = l.find('configItem/name').text
105 variants = l.findall('variantList/variant')
106 for v in progress_bar(variants, 'variant'):
107 variant = v.find('configItem/name').text
108 tool(l=layout, v=variant)
110 for option in progress_bar(options, 'option '):
111 tool(l=layout, v=variant, o=option)
116 'libxkbcommon': xkbcommontool,
120 parser = argparse.ArgumentParser(
121 description='Tool to test all layout/variant/option combinations.'
123 parser.add_argument('path', metavar='/path/to/evdev.xml',
125 default=DEFAULT_RULES_XML,
126 help='Path to xkeyboard-config\'s evdev.xml')
127 parser.add_argument('--tool', choices=tools.keys(),
128 type=str, default='libxkbcommon',
129 help='parsing tool to use')
130 args = parser.parse_args()
132 tool = tools[args.tool]
134 with open(args.path) as f:
135 root = ET.fromstring(f.read())
139 if __name__ == '__main__':