1#!/usr/bin/env python3 2 3# SPDX-FileCopyrightText: 2021 Pino Toscano <pino@debian.org> 4# SPDX-License-Identifier: GPL-2.0-or-later 5 6import os 7import re 8import sys 9from collections import namedtuple 10 11 12UsbIds = namedtuple('UsbIds', 13 ['classes', 'subclasses', 'protocols', 'date']) 14 15 16def parse(fn): 17 classes = [] 18 subclasses = [] 19 protocols = [] 20 date = None 21 22 class_re = re.compile("^C ([0-9a-fA-F]{2})\\s+(.+)$") 23 subclass_re = re.compile("^\t([0-9a-fA-F]{2})\\s+(.+)$") 24 protocol_re = re.compile("^\t\t([0-9a-fA-F]{2})\\s+(.+)$") 25 26 with open(fn, 'r', encoding='iso-8859-1') as f: 27 in_class = False 28 in_subclass = False 29 for line in f: 30 line = line.rstrip('\n') 31 line_len = len(line) 32 33 if line_len > 0 and line[0] == '#': 34 if line.startswith('# Date:'): 35 date = line.split(':', maxsplit=1)[1].strip() 36 continue 37 38 if line_len == 0 or (line[0].isalnum() and line[0] != 'C'): 39 in_class = False 40 in_subclass = False 41 continue 42 43 m = class_re.fullmatch(line) 44 if m: 45 classes.append(m[2].rstrip()) 46 in_class = True 47 continue 48 if in_class: 49 m = subclass_re.fullmatch(line) 50 if m: 51 in_subclass = True 52 subclasses.append(m[2].rstrip()) 53 continue 54 if in_class and in_subclass: 55 m = protocol_re.fullmatch(line) 56 if m: 57 protocols.append(m[2].rstrip()) 58 continue 59 60 in_class = False 61 in_subclass = False 62 63 parsed = UsbIds(classes, subclasses, protocols, date) 64 65 return parsed 66 67 68def output(strings, context): 69 for s in strings: 70 print('i18nc("{}", "{}");'.format(context, s)) 71 72 73if __name__ == '__main__': 74 if len(sys.argv) != 2: 75 print('Usage: {} /path/to/usb.ids'.format(sys.argv[0]), 76 file=sys.stderr) 77 sys.exit(1) 78 79 filename = sys.argv[1] 80 parsed = parse(filename) 81 classes = sorted(list(set(parsed.classes))) 82 subclasses = sorted(list(set(parsed.subclasses))) 83 if parsed.date: 84 date_str = parsed.date 85 else: 86 date_str = 'n/a' 87 print('// Generated from {} with date \'{}\''.format( 88 os.path.basename(filename), date_str)) 89 output(classes, 'USB device class') 90 output(subclasses, 'USB device subclass') 91