File indexing completed on 2024-05-19 05:29:59

0001 #!/usr/bin/env python3
0002 
0003 # SPDX-FileCopyrightText: 2021 Pino Toscano <pino@debian.org>
0004 # SPDX-License-Identifier: GPL-2.0-or-later
0005 
0006 import os
0007 import re
0008 import sys
0009 from collections import namedtuple
0010 
0011 
0012 UsbIds = namedtuple('UsbIds',
0013                     ['classes', 'subclasses', 'protocols', 'date'])
0014 
0015 
0016 def parse(fn):
0017     classes = []
0018     subclasses = []
0019     protocols = []
0020     date = None
0021 
0022     class_re = re.compile("^C ([0-9a-fA-F]{2})\\s+(.+)$")
0023     subclass_re = re.compile("^\t([0-9a-fA-F]{2})\\s+(.+)$")
0024     protocol_re = re.compile("^\t\t([0-9a-fA-F]{2})\\s+(.+)$")
0025 
0026     with open(fn, 'r', encoding='iso-8859-1') as f:
0027         in_class = False
0028         in_subclass = False
0029         for line in f:
0030             line = line.rstrip('\n')
0031             line_len = len(line)
0032 
0033             if line_len > 0 and line[0] == '#':
0034                 if line.startswith('# Date:'):
0035                     date = line.split(':', maxsplit=1)[1].strip()
0036                 continue
0037 
0038             if line_len == 0 or (line[0].isalnum() and line[0] != 'C'):
0039                 in_class = False
0040                 in_subclass = False
0041                 continue
0042 
0043             m = class_re.fullmatch(line)
0044             if m:
0045                 classes.append(m[2].rstrip())
0046                 in_class = True
0047                 continue
0048             if in_class:
0049                 m = subclass_re.fullmatch(line)
0050                 if m:
0051                     in_subclass = True
0052                     subclasses.append(m[2].rstrip())
0053                     continue
0054             if in_class and in_subclass:
0055                 m = protocol_re.fullmatch(line)
0056                 if m:
0057                     protocols.append(m[2].rstrip())
0058                     continue
0059 
0060             in_class = False
0061             in_subclass = False
0062 
0063     parsed = UsbIds(classes, subclasses, protocols, date)
0064 
0065     return parsed
0066 
0067 
0068 def output(strings, context):
0069     for s in strings:
0070         print('i18nc("{}", "{}");'.format(context, s))
0071 
0072 
0073 if __name__ == '__main__':
0074     if len(sys.argv) != 2:
0075         print('Usage: {} /path/to/usb.ids'.format(sys.argv[0]),
0076               file=sys.stderr)
0077         sys.exit(1)
0078 
0079     filename = sys.argv[1]
0080     parsed = parse(filename)
0081     classes = sorted(list(set(parsed.classes)))
0082     subclasses = sorted(list(set(parsed.subclasses)))
0083     if parsed.date:
0084         date_str = parsed.date
0085     else:
0086         date_str = 'n/a'
0087     print('// Generated from {} with date \'{}\''.format(
0088               os.path.basename(filename), date_str))
0089     output(classes, 'USB device class')
0090     output(subclasses, 'USB device subclass')