Home | History | Annotate | Download | only in tools
      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 
      5 import itertools
      6 import optparse
      7 import re
      8 
      9 VENDOR_PATTERN = re.compile("^(?P<id>[0-9a-fA-F]{4})\s+(?P<name>.+)$")
     10 PRODUCT_PATTERN = re.compile("^\t(?P<id>[0-9a-fA-F]{4})\s+(?P<name>.+)$")
     11 
     12 def EscapeName(name):
     13   name = name.replace("\\", "\\\\")
     14   name = name.replace("\"", "\\\"")
     15   name = name.replace("?", "\?")
     16   return name
     17 
     18 def 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 
     48 def 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 
     65 def 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 
     81 if __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 
     96 namespace 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