SDL_GameControllerDB/check.py
Philippe Groarke 1c6b4971c5 formatting : Sort db by human readable name.
This will hopefully help with duplicates.
2017-10-14 22:51:30 -04:00

155 lines
5.5 KiB
Python
Executable file

#!/usr/bin/env python3
import fileinput
import string
import sys
from collections import defaultdict
import collections
import shutil
success = True
current_line = ""
entry_dict = defaultdict(tuple)
dupe_dict = defaultdict(list)
def get_current_line():
return current_line
def error (message):
global success
success = False
print("Error at line #" + str(fileinput.lineno()), ":", message)
print(get_current_line())
def check_guid (guid):
if len (guid) != 32:
error ("The length of the guid string must be equal to 32")
for c in guid:
if not c in string.hexdigits:
error ("Each character in guid string must be a hex character "
+ string.hexdigits)
def check_mapping (mappingstring):
keys = ["platform", "leftx", "lefty", "rightx", "righty", "a", "b", \
"back", "dpdown", \
"dpleft", "dpright", "dpup", "guide", "leftshoulder", "leftstick", \
"lefttrigger", "rightshoulder", "rightstick", "righttrigger", \
"start", "x", "y"]
platforms = ["Linux", "Mac OS X", "Windows"]
mappings = mappingstring.split (',')
for mapping in mappings:
if not mapping:
continue
if len (mapping.split(':')) != 2:
error ("Invalid mapping : " + mapping)
continue
key = mapping.split (':')[0]
value = mapping.split (':')[1]
if not key in keys:
error ("Invalid key \"" + key + "\" in mapping string")
# Check values
if key == "platform":
if value not in platforms:
error ("Invalid platform \"" + value + "\" in mapping string")
else:
if not value:
continue
if not value[0] in ['a', 'h', 'b']:
error ("Invalid value \"" + value + "\" for key \"" + key +
"\". Should start with a, b, or h")
elif value[0] in ['a', 'b']:
if not value[1:].isnumeric():
error ("Invalid value \"" + value + "\" for key \"" + key +
"\". Should be followed by a number after 'a' or " +
"'b'")
else:
dpad_positions = map(str, [0, 1, 2, 4, 8, 1|2, 2|4, 4|8, 8|1])
dpad_index = value[1:].split ('.')[0]
dpad_position = value[1:].split ('.')[1]
if not dpad_index.isnumeric():
error ("Invalid value \"" + value + "\" for key \"" + key +
"\". Dpad index \"" + dpad_index + "\" should be " +
"a number")
if not dpad_position in dpad_positions:
error ("Invalid value \"" + value + "\" for key \"" + key +
"\". Dpad position \"" + dpad_position + "\" " +
"should be one of" + ', '.join(dpad_positions))
def get_platform (mappingstring):
mappings = mappingstring.split (',')
for mapping in mappings:
if not mapping:
continue
key = mapping.split(':')[0]
value = mapping.split(':')[1]
if key == "platform":
return value
error ("No platform specified " + mapping)
def has_duplicate(guids):
seen = set()
seen_add = seen.add
seen_twice = set( x for x in guids if x in seen or seen_add(x) )
return len(seen_twice) != 0
def check_duplicates(guid, platform):
guids = list(dupe_dict[platform])
guids.append(guid)
if has_duplicate(guids):
error("\nDuplicate entry :")
print("Original at line #" + entry_dict[guid][0] +
":\n" + entry_dict[guid][1])
else:
dupe_dict[platform].append(guid)
entry_dict[guid] = (str(fileinput.lineno()), get_current_line())
def do_tests():
global current_line
for line in fileinput.input():
current_line = line
if line.startswith('#') or line == '\n':
continue
splitted = line[:-1].split(',', 2)
if len(splitted) < 3 or not splitted[0] or not splitted[1] \
or not splitted[2]:
error ("Either GUID/Name/Mappingstring is missing or empty")
check_guid(splitted[0])
check_mapping(splitted[2])
check_duplicates(splitted[0], get_platform(splitted[2]))
def sort_by_name():
sorted_dict = dict({"Windows": list(tuple()), "Mac OS X": list(tuple()), \
"Linux": list(tuple())})
for line in fileinput.input():
if line.startswith('#') or line == '\n':
continue
splitted = line[:-1].split(',', 2)
if len(splitted) < 3 or not splitted[0] or not splitted[1] \
or not splitted[2]:
continue
platform = get_platform(splitted[2])
sorted_dict[platform].append((splitted[1], line))
out_file = open("gamecontrollerdb_sorted.txt", 'w')
for platform, name_tuples in sorted_dict.items():
if platform != "Windows":
out_file.write("\n")
out_file.write("# " + platform + "\n")
for tuples in sorted(name_tuples, key=lambda tup: tup[0].lower()):
out_file.write(tuples[1])
out_file.close()
shutil.copyfile(fileinput.filename(), ".bak." + fileinput.filename())
shutil.move("gamecontrollerdb_sorted.txt", "gamecontrollerdb.txt")
def main():
do_tests()
if success:
print("No mapping errors found. Sorting by human readable name.")
sort_by_name()
else:
sys.exit(1)
if __name__ == "__main__":
main()