Blame libevdev/make-event-names.py

Packit Service 970bec
#! /usr/libexec/platform-python
Packit 57e92c
# Parses linux/input.h scanning for #define KEY_FOO 134
Packit 57e92c
# Prints C header files or Python files that can be used as
Packit 57e92c
# mapping and lookup tables.
Packit 57e92c
#
Packit 57e92c
Packit 57e92c
from __future__ import print_function
Packit 57e92c
import re
Packit 57e92c
import sys
Packit 57e92c
Packit 57e92c
class Bits(object):
Packit 57e92c
	def __init__(self):
Packit 57e92c
		self.max_codes = {}
Packit 57e92c
Packit 57e92c
prefixes = [
Packit 57e92c
		"EV_",
Packit 57e92c
		"REL_",
Packit 57e92c
		"ABS_",
Packit 57e92c
		"KEY_",
Packit 57e92c
		"BTN_",
Packit 57e92c
		"LED_",
Packit 57e92c
		"SND_",
Packit 57e92c
		"MSC_",
Packit 57e92c
		"SW_",
Packit 57e92c
		"FF_",
Packit 57e92c
		"SYN_",
Packit 57e92c
		"REP_",
Packit 57e92c
		"INPUT_PROP_",
Packit 57e92c
		"MT_TOOL_",
Packit 57e92c
]
Packit 57e92c
Packit 57e92c
duplicates = [
Packit 57e92c
		"EV_VERSION",
Packit 57e92c
		"BTN_MISC",
Packit 57e92c
		"BTN_MOUSE",
Packit 57e92c
		"BTN_JOYSTICK",
Packit 57e92c
		"BTN_GAMEPAD",
Packit 57e92c
		"BTN_DIGI",
Packit 57e92c
		"BTN_WHEEL",
Packit 57e92c
		"BTN_TRIGGER_HAPPY",
Packit 57e92c
		"SW_MAX",
Packit 57e92c
		"REP_MAX",
Packit 57e92c
]
Packit 57e92c
Packit 57e92c
btn_additional = [
Packit 57e92c
		[0, "BTN_A"],
Packit 57e92c
		[0, "BTN_B"],
Packit 57e92c
		[0, "BTN_X"],
Packit 57e92c
		[0, "BTN_Y"],
Packit 57e92c
]
Packit 57e92c
Packit 57e92c
code_prefixes = [
Packit 57e92c
		"REL_",
Packit 57e92c
		"ABS_",
Packit 57e92c
		"KEY_",
Packit 57e92c
		"BTN_",
Packit 57e92c
		"LED_",
Packit 57e92c
		"SND_",
Packit 57e92c
		"MSC_",
Packit 57e92c
		"SW_",
Packit 57e92c
		"FF_",
Packit 57e92c
		"SYN_",
Packit 57e92c
		"REP_",
Packit 57e92c
]
Packit 57e92c
Packit 57e92c
def print_bits(bits, prefix):
Packit 57e92c
	if  not hasattr(bits, prefix):
Packit 57e92c
		return
Packit 57e92c
	print("static const char * const %s_map[%s_MAX + 1] = {" % (prefix, prefix.upper()))
Packit 57e92c
	for val, name in list(getattr(bits, prefix).items()):
Packit 57e92c
		print("	[%s] = \"%s\"," % (name, name))
Packit 57e92c
	if prefix == "key":
Packit 57e92c
		for val, name in list(getattr(bits, "btn").items()):
Packit 57e92c
			print("	[%s] = \"%s\"," % (name, name))
Packit 57e92c
	print("};")
Packit 57e92c
	print("")
Packit 57e92c
Packit 57e92c
def print_map(bits):
Packit 57e92c
	print("static const char * const * const event_type_map[EV_MAX + 1] = {")
Packit 57e92c
Packit 57e92c
	for prefix in prefixes:
Packit 57e92c
		if prefix in ["BTN_", "EV_", "INPUT_PROP_", "MT_TOOL_"]:
Packit 57e92c
			continue
Packit 57e92c
		print("	[EV_%s] = %s_map," % (prefix[:-1], prefix[:-1].lower()))
Packit 57e92c
Packit 57e92c
	print("};")
Packit 57e92c
	print("")
Packit 57e92c
Packit 57e92c
	print("#if __clang__")
Packit 57e92c
	print("#pragma clang diagnostic push")
Packit 57e92c
	print("#pragma clang diagnostic ignored \"-Winitializer-overrides\"")
Packit 57e92c
	print("#else")
Packit 57e92c
	print("#pragma GCC diagnostic push")
Packit 57e92c
	print("#pragma GCC diagnostic ignored \"-Woverride-init\"")
Packit 57e92c
	print("#endif")
Packit 57e92c
	print("static const int ev_max[EV_MAX + 1] = {")
Packit 57e92c
	print("	[0 ... EV_MAX] = -1,")
Packit 57e92c
	for prefix in prefixes:
Packit 57e92c
		if prefix in ["BTN_", "EV_", "INPUT_PROP_", "MT_TOOL_"]:
Packit 57e92c
			continue
Packit 57e92c
		print("	[EV_%s] = %s_MAX," % (prefix[:-1], prefix[:-1]))
Packit 57e92c
	print("};")
Packit 57e92c
	print("#if __clang__")
Packit 57e92c
	print("#pragma clang diagnostic pop /* \"-Winitializer-overrides\" */")
Packit 57e92c
	print("#else")
Packit 57e92c
	print("#pragma GCC diagnostic pop /* \"-Woverride-init\" */")
Packit 57e92c
	print("#endif");
Packit 57e92c
	print("")
Packit 57e92c
Packit 57e92c
def print_lookup(bits, prefix):
Packit 57e92c
	if not hasattr(bits, prefix):
Packit 57e92c
		return
Packit 57e92c
Packit 57e92c
	names = list(getattr(bits, prefix).items())
Packit 57e92c
	if prefix == "btn":
Packit 57e92c
		names = names + btn_additional;
Packit 57e92c
Packit 57e92c
	# We need to manually add the _MAX codes because some are
Packit 57e92c
	# duplicates
Packit 57e92c
	maxname = "%s_MAX" % (prefix.upper())
Packit 57e92c
	if maxname in duplicates:
Packit 57e92c
		names.append((bits.max_codes[maxname], maxname))
Packit 57e92c
Packit 57e92c
	for val, name in sorted(names, key=lambda e: e[1]):
Packit 57e92c
		print("	{ .name = \"%s\", .value = %s }," % (name, name))
Packit 57e92c
Packit 57e92c
def print_lookup_table(bits):
Packit 57e92c
	print("struct name_entry {")
Packit 57e92c
	print("	const char *name;")
Packit 57e92c
	print("	unsigned int value;")
Packit 57e92c
	print("};")
Packit 57e92c
	print("")
Packit 57e92c
	print("static const struct name_entry tool_type_names[] = {")
Packit 57e92c
	print_lookup(bits, "mt_tool")
Packit 57e92c
	print("};")
Packit 57e92c
	print("")
Packit 57e92c
	print("static const struct name_entry ev_names[] = {")
Packit 57e92c
	print_lookup(bits, "ev")
Packit 57e92c
	print("};")
Packit 57e92c
	print("")
Packit 57e92c
Packit 57e92c
	print("static const struct name_entry code_names[] = {")
Packit 57e92c
	for prefix in sorted(code_prefixes, key=lambda e: e):
Packit 57e92c
		print_lookup(bits, prefix[:-1].lower())
Packit 57e92c
	print("};")
Packit 57e92c
	print("")
Packit 57e92c
	print("static const struct name_entry prop_names[] = {")
Packit 57e92c
	print_lookup(bits, "input_prop")
Packit 57e92c
	print("};")
Packit 57e92c
	print("")
Packit 57e92c
Packit 57e92c
def print_mapping_table(bits):
Packit 57e92c
	print("/* THIS FILE IS GENERATED, DO NOT EDIT */")
Packit 57e92c
	print("")
Packit 57e92c
	print("#ifndef EVENT_NAMES_H")
Packit 57e92c
	print("#define EVENT_NAMES_H")
Packit 57e92c
	print("")
Packit 57e92c
Packit 57e92c
	for prefix in prefixes:
Packit 57e92c
		if prefix == "BTN_":
Packit 57e92c
			continue
Packit 57e92c
		print_bits(bits, prefix[:-1].lower())
Packit 57e92c
Packit 57e92c
	print_map(bits)
Packit 57e92c
	print_lookup_table(bits)
Packit 57e92c
Packit 57e92c
	print("#endif /* EVENT_NAMES_H */")
Packit 57e92c
Packit 57e92c
def parse_define(bits, line):
Packit 57e92c
	m = re.match(r"^#define\s+(\w+)\s+(\w+)", line)
Packit 57e92c
	if m == None:
Packit 57e92c
		return
Packit 57e92c
Packit 57e92c
	name = m.group(1)
Packit 57e92c
Packit 57e92c
	try:
Packit 57e92c
		value = int(m.group(2), 0)
Packit 57e92c
	except ValueError:
Packit 57e92c
		return
Packit 57e92c
Packit 57e92c
	for prefix in prefixes:
Packit 57e92c
		if not name.startswith(prefix):
Packit 57e92c
			continue
Packit 57e92c
Packit 57e92c
		if name.endswith("_MAX"):
Packit 57e92c
			bits.max_codes[name] = value
Packit 57e92c
Packit 57e92c
		if name in duplicates:
Packit 57e92c
			return
Packit 57e92c
Packit 57e92c
		attrname = prefix[:-1].lower()
Packit 57e92c
Packit 57e92c
		if not hasattr(bits, attrname):
Packit 57e92c
			setattr(bits, attrname, {})
Packit 57e92c
		b = getattr(bits, attrname)
Packit 57e92c
		b[value] = name
Packit 57e92c
Packit 57e92c
def parse(fp):
Packit 57e92c
	bits = Bits()
Packit 57e92c
Packit 57e92c
	lines = fp.readlines()
Packit 57e92c
	for line in lines:
Packit 57e92c
		if not line.startswith("#define"):
Packit 57e92c
			continue
Packit 57e92c
		parse_define(bits, line)
Packit 57e92c
Packit 57e92c
	return bits
Packit 57e92c
Packit 57e92c
def usage(prog):
Packit 57e92c
	print("Usage: cat <files> | %s" % prog)
Packit 57e92c
Packit 57e92c
if __name__ == "__main__":
Packit 57e92c
	if len(sys.argv) != 1:
Packit 57e92c
		usage(sys.argv[0])
Packit 57e92c
		sys.exit(2)
Packit 57e92c
Packit 57e92c
	bits = parse(sys.stdin)
Packit 57e92c
	print_mapping_table(bits)