1# Copyright (c) 2012 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import itertools 6import optparse 7import re 8 9VENDOR_PATTERN = re.compile("^(?P<id>[0-9a-fA-F]{4})\s+(?P<name>.+)$") 10PRODUCT_PATTERN = re.compile("^\t(?P<id>[0-9a-fA-F]{4})\s+(?P<name>.+)$") 11 12def EscapeName(name): 13 name = name.replace("\\", "\\\\") 14 name = name.replace("\"", "\\\"") 15 name = name.replace("?", "\?") 16 return name 17 18def ParseTable(input_path): 19 input_file = open(input_path, "r") 20 input = input_file.read().split("\n") 21 input_file.close() 22 23 table = {} 24 vendor = None 25 26 for line in input: 27 vendor_match = VENDOR_PATTERN.match(line) 28 if vendor_match: 29 if vendor: 30 table[vendor["id"]] = vendor 31 vendor = {} 32 vendor["id"] = int(vendor_match.group("id"), 16) 33 vendor["name"] = vendor_match.group("name") 34 vendor["products"] = [] 35 continue 36 37 product_match = PRODUCT_PATTERN.match(line) 38 if product_match: 39 if not vendor: 40 raise Exception("Product seems to appear before vendor.") 41 product = {} 42 product["id"] = int(product_match.group("id"), 16) 43 product["name"] = product_match.group("name") 44 vendor["products"].append(product) 45 46 return table 47 48def GenerateDeviceDefinitions(table): 49 output = "" 50 51 for vendor_id in sorted(table.keys()): 52 vendor = table[vendor_id] 53 if len(vendor["products"]) == 0: 54 continue 55 56 output += "static const UsbProduct vendor_%.4x_products[] = {\n" % \ 57 vendor["id"] 58 for product in vendor["products"]: 59 output += " {0x%.4x, \"%s\"},\n" % (product["id"], 60 EscapeName(product["name"])) 61 output += "};\n" 62 63 return output 64 65def GenerateVendorDefinitions(table): 66 output = "const size_t UsbIds::vendor_size_ = %d;\n" % len(table.keys()) 67 output += "const UsbVendor UsbIds::vendors_[] = {\n" 68 69 for vendor_id in sorted(table.keys()): 70 vendor = table[vendor_id] 71 72 product_table = "NULL" 73 if len(vendor["products"]) != 0: 74 product_table = "vendor_%.4x_products" % (vendor["id"]) 75 output += " {0x%.4x, \"%s\", %d, %s},\n" % (vendor["id"], 76 EscapeName(vendor["name"]), len(vendor["products"]), product_table) 77 78 output += "};\n" 79 return output 80 81if __name__ == "__main__": 82 parser = optparse.OptionParser( 83 description="Generates a C++ USB ID lookup table.") 84 parser.add_option("-i", "--input", help="Path to usb.ids") 85 parser.add_option("-o", "--output", help="Output file path") 86 87 (opts, args) = parser.parse_args() 88 table = ParseTable(opts.input) 89 90 output = """// Generated from %s 91#ifndef GENERATED_USB_IDS_H_ 92#define GENERATED_USB_IDS_H_ 93 94#include "device/usb/usb_ids.h" 95 96namespace device { 97 98""" % (opts.input) 99 output += GenerateDeviceDefinitions(table) 100 output += GenerateVendorDefinitions(table) 101 output += """ 102 103} // namespace device 104 105#endif // GENERATED_USB_IDS_H_ 106""" 107 108 output_file = open(opts.output, "w+") 109 output_file.write(output) 110 output_file.close() 111