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