# 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()