test: xkeyboard-config: use argparse for the path and the tool selection
[platform/upstream/libxkbcommon.git] / test / xkeyboard-config-test.py.in
1 #!/usr/bin/env python
2 import argparse
3 import sys
4 import subprocess
5 import os
6 import xml.etree.ElementTree as ET
7
8
9 verbose = True
10
11 DEFAULT_RULES_XML = '@XKB_CONFIG_ROOT@/rules/evdev.xml'
12
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')])
16
17
18 # The function generating the progress bar (if any).
19 progress_bar = lambda x, desc: x
20 if os.isatty(sys.stdout.fileno()):
21     try:
22         from tqdm import tqdm
23         progress_bar = tqdm
24
25         verbose = False
26     except ImportError:
27         pass
28
29
30 def xkbcommontool(r='evdev', m='pc105', l='us', v=None, o=None):
31     args = [
32         'rmlvo-to-keymap',
33         '--rules', r,
34         '--model', m,
35         '--layout', l,
36     ]
37     if v is not None:
38         args += ['--variant', v]
39     if o is not None:
40         args += ['--options', o]
41
42     if verbose:
43         print(':: {}'.format(' '.join(args)))
44
45     try:
46         output = subprocess.check_output(args, stderr=subprocess.STDOUT)
47         if verbose:
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'))
52         sys.exit(1)
53
54
55 def xkbcomp(r='evdev', m='pc105', l='us', v='', o=''):
56     args = ['setxkbmap', '-print']
57     if r is not None:
58         args.append('-rules')
59         args.append('{}'.format(r))
60     if m is not None:
61         args.append('-model')
62         args.append('{}'.format(m))
63     if l is not None:
64         args.append('-layout')
65         args.append('{}'.format(l))
66     if o is not None:
67         args.append('-option')
68         args.append('{}'.format(o))
69
70     if verbose:
71         print(':: {}'.format(' '.join(args)))
72
73     try:
74         xkbcomp_args = ['xkbcomp', '-xkb', '-', '-']
75
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'))
86
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'))
91
92
93 def parse(root, tool):
94     layouts = root.findall('layoutList/layout')
95
96     options = [
97         e.text
98         for e in root.findall('optionList/group/option/configItem/name')
99     ]
100
101     for l in progress_bar(layouts, 'layout '):
102         layout = l.find('configItem/name').text
103         tool(l=layout)
104
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)
109
110             for option in progress_bar(options, 'option '):
111                 tool(l=layout, v=variant, o=option)
112
113
114 def main(args):
115     tools = {
116         'libxkbcommon': xkbcommontool,
117         'xkbcomp': xkbcomp,
118     }
119
120     parser = argparse.ArgumentParser(
121         description='Tool to test all layout/variant/option combinations.'
122     )
123     parser.add_argument('path', metavar='/path/to/evdev.xml',
124                         nargs='?', type=str,
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()
131
132     tool = tools[args.tool]
133
134     with open(args.path) as f:
135         root = ET.fromstring(f.read())
136         parse(root, tool)
137
138
139 if __name__ == '__main__':
140     main(sys.argv)