• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2
3import re, sys, itertools
4
5import perfect_hash
6
7pattern = re.compile(r'^#define\s+XKB_KEY_(?P<name>\w+)\s+(?P<value>0x[0-9a-fA-F]+)\s')
8matches = [pattern.match(line) for line in open(sys.argv[1])]
9entries = [(m.group("name"), int(m.group("value"), 16)) for m in matches if m]
10
11entries_isorted = sorted(entries, key=lambda e: e[0].lower())
12entries_kssorted = sorted(entries, key=lambda e: e[1])
13
14print('''
15/**
16 * This file comes from libxkbcommon and was generated by makekeys.py
17 * You can always fetch the latest version from:
18 * https://raw.github.com/xkbcommon/libxkbcommon/master/src/ks_tables.h
19 */
20''')
21
22entry_offsets = {}
23
24print('''
25#ifdef __GNUC__
26#pragma GCC diagnostic push
27#pragma GCC diagnostic ignored "-Woverlength-strings"
28#endif
29static const char *keysym_names =
30'''.strip())
31offs = 0
32for (name, _) in entries_isorted:
33    entry_offsets[name] = offs
34    print('    "{name}\\0"'.format(name=name))
35    offs += len(name) + 1
36print('''
37;
38#ifdef __GNUC__
39#pragma GCC diagnostic pop
40#endif
41'''.strip())
42
43
44template = r'''
45static const uint16_t keysym_name_G[] = {
46    $G
47};
48
49static size_t
50keysym_name_hash_f(const char *key, const char *T)
51{
52    size_t sum = 0;
53    for (size_t i = 0; key[i] != '\0'; i++)
54        sum += T[i % $NS] * key[i];
55    return sum % $NG;
56}
57
58static size_t
59keysym_name_perfect_hash(const char *key)
60{
61    return (
62        keysym_name_G[keysym_name_hash_f(key, "$S1")] +
63        keysym_name_G[keysym_name_hash_f(key, "$S2")]
64    ) % $NG;
65}
66'''
67print(perfect_hash.generate_code(
68    keys=[name for name, value in entries_isorted],
69    template=template,
70))
71
72print('''
73struct name_keysym {
74    xkb_keysym_t keysym;
75    uint32_t offset;
76};\n''')
77
78def print_entries(x):
79    for (name, value) in x:
80        print('    {{ 0x{value:08x}, {offs} }}, /* {name} */'.format(offs=entry_offsets[name], value=value, name=name))
81
82print('static const struct name_keysym name_to_keysym[] = {')
83print_entries(entries_isorted)
84print('};\n')
85
86# *.sort() is stable so we always get the first keysym for duplicate
87print('static const struct name_keysym keysym_to_name[] = {')
88print_entries(next(g[1]) for g in itertools.groupby(entries_kssorted, key=lambda e: e[1]))
89print('};')
90