| # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import itertools |
| import optparse |
| import re |
| |
| VENDOR_PATTERN = re.compile("^(?P<id>[0-9a-fA-F]{4})\s+(?P<name>.+)$") |
| PRODUCT_PATTERN = re.compile("^\t(?P<id>[0-9a-fA-F]{4})\s+(?P<name>.+)$") |
| |
| def EscapeName(name): |
| name = name.replace("\\", "\\\\") |
| name = name.replace("\"", "\\\"") |
| name = name.replace("?", "\?") |
| return name |
| |
| def ParseTable(input_path): |
| input_file = open(input_path, "r") |
| input = input_file.read().split("\n") |
| input_file.close() |
| |
| table = {} |
| vendor = None |
| |
| for line in input: |
| vendor_match = VENDOR_PATTERN.match(line) |
| if vendor_match: |
| if vendor: |
| table[vendor["id"]] = vendor |
| vendor = {} |
| vendor["id"] = int(vendor_match.group("id"), 16) |
| vendor["name"] = vendor_match.group("name") |
| vendor["products"] = [] |
| continue |
| |
| product_match = PRODUCT_PATTERN.match(line) |
| if product_match: |
| if not vendor: |
| raise Exception("Product seems to appear before vendor.") |
| product = {} |
| product["id"] = int(product_match.group("id"), 16) |
| product["name"] = product_match.group("name") |
| vendor["products"].append(product) |
| |
| return table |
| |
| def GenerateDeviceDefinitions(table): |
| output = "" |
| |
| for vendor_id in sorted(table.keys()): |
| vendor = table[vendor_id] |
| if len(vendor["products"]) == 0: |
| continue |
| |
| output += "static const UsbProduct vendor_%.4x_products[] = {\n" % \ |
| vendor["id"] |
| for product in vendor["products"]: |
| output += " {0x%.4x, \"%s\"},\n" % (product["id"], |
| EscapeName(product["name"])) |
| output += "};\n" |
| |
| return output |
| |
| def GenerateVendorDefinitions(table): |
| output = "const size_t UsbIds::vendor_size_ = %d;\n" % len(table.keys()) |
| output += "const UsbVendor UsbIds::vendors_[] = {\n" |
| |
| for vendor_id in sorted(table.keys()): |
| vendor = table[vendor_id] |
| |
| product_table = "NULL" |
| if len(vendor["products"]) != 0: |
| product_table = "vendor_%.4x_products" % (vendor["id"]) |
| output += " {0x%.4x, \"%s\", %d, %s},\n" % (vendor["id"], |
| EscapeName(vendor["name"]), len(vendor["products"]), product_table) |
| |
| output += "};\n" |
| return output |
| |
| if __name__ == "__main__": |
| parser = optparse.OptionParser( |
| description="Generates a C++ USB ID lookup table.") |
| parser.add_option("-i", "--input", help="Path to usb.ids") |
| parser.add_option("-o", "--output", help="Output file path") |
| |
| (opts, args) = parser.parse_args() |
| table = ParseTable(opts.input) |
| |
| output = """// Generated from %s |
| #ifndef GENERATED_USB_IDS_H_ |
| #define GENERATED_USB_IDS_H_ |
| |
| #include "device/usb/usb_ids.h" |
| |
| namespace device { |
| |
| """ % (opts.input) |
| output += GenerateDeviceDefinitions(table) |
| output += GenerateVendorDefinitions(table) |
| output += """ |
| |
| } // namespace device |
| |
| #endif // GENERATED_USB_IDS_H_ |
| """ |
| |
| output_file = open(opts.output, "w+") |
| output_file.write(output) |
| output_file.close() |