auto import from //depot/cupcake/@135843
diff --git a/gen-charmap.py b/gen-charmap.py
new file mode 100644
index 0000000..3c86350
--- /dev/null
+++ b/gen-charmap.py
@@ -0,0 +1,180 @@
+#!/usr/bin/python
+#
+# a python script used to generate some C constant tables from a key charmap file
+#
+# usage:
+#    progname file.kcm > charmap-tab.h
+#
+import sys, os, string, re
+
+header = """\
+#include "android_charmap.h"
+
+/* the following is automatically generated by the 'gen-charmap.py' script
+ * do not touch. the generation command was:
+ *   gen-charmap.py\
+"""
+
+header2 = """
+ */
+"""
+
+kmap_header = """\
+static const AKeyEntry  _%(name)s_keys[] =
+{
+   /* keycode                   base   caps    fn  caps+fn   number */
+"""
+
+
+kmap_footer = """\
+};
+
+static const AKeyCharmap  _%(name)s_charmap =
+{
+    _%(name)s_keys,
+    %(count)d,
+    "%(name)s"
+};
+"""
+
+
+re_mapname = re.compile( r".*/(\w+).kcm" )
+re_start = re.compile( r"(\w+)\s*(.*)" )
+re_char  = re.compile( r"('.')\s*(.*)" )
+re_hex   = re.compile( r"(0x\w+)\s*(.*)" )
+
+specials = { 'COMMA': 'Comma',
+             'PERIOD': 'Period',
+             'AT': 'At',
+             'LEFT_BRACKET': 'LeftBracket',
+             'RIGHT_BRACKET': 'RightBracket',
+             'SLASH': 'Slash',
+             'BACKSLASH': 'Backslash',
+             'GRAVE': 'Grave',
+             'MINUS': 'Minus',
+             'EQUALS': 'Equals',
+             'SEMICOLON': 'Semicolon',
+             'APOSTROPHE': 'Apostrophe',
+             'SPACE': 'Space',
+             'ENTER': 'Enter',
+             'TAB': 'Tab'
+           }
+
+entries = []
+
+def match_char_or_hex(line):
+    m = re_char.match(line)
+    if not m:
+        m = re_hex.match(line)
+    return m
+
+def quote(s):
+    if s == "'''":
+        s = "'\\''"
+    elif s == "'\\'":
+        s = "'\\\\'"
+    return s
+
+def process_line(line,result):
+    m = re_start.match(line)
+    if not m:
+        print "bad bad line: " + line
+        return -1
+    keycode = m.group(1)
+    line    = m.group(2)
+    m = match_char_or_hex(line)
+    if not m:
+        print "character expected in: " + line
+        return -1
+    base = quote(m.group(1))
+    line = m.group(2)
+    m = match_char_or_hex(line)
+    if not m:
+        print "character expected in: " + line
+        return -1
+    caps = quote(m.group(1))
+    line = m.group(2)
+    m = match_char_or_hex(line)
+    if not m:
+        print "character expected in: " + line
+        return -1
+    fn = quote(m.group(1))
+    line = m.group(2)
+    m = match_char_or_hex(line)
+    if not m:
+        print "character expected in: " + line
+        return -1
+    caps_fn = quote(m.group(1))
+    line = m.group(2)
+    m = match_char_or_hex(line)
+    if not m:
+        print "character expected in: " + line
+        return -1
+    number = quote(m.group(1))
+
+    if specials.has_key(keycode):
+        keycode = specials[keycode]
+    keycode = "kKeyCode" + keycode
+
+    result.append( (keycode,base,caps,fn,caps_fn,number) )
+    return 0
+
+def process_file( file ):
+    result = []
+    fp = open(file,"rb")
+    for line in fp.xreadlines():
+        line = line.strip()
+        if not line:   # skip empty lines
+            continue
+        if line[0] == '#' or line[0] == '[':  # skip
+            continue
+        if process_line(line,result) < 0:
+            break
+    fp.close()
+    return result
+
+class KMap:
+    def __init__(self,name,results):
+        self.name    = name
+        self.results = results
+
+    def dump(self):
+        t = { 'name': self.name, 'count':len(self.results) }
+        print kmap_header % t
+        for item in self.results:
+            print "    { %-22s, %5s, %5s, %5s, %6s, %5s }," % item
+        print kmap_footer % t
+
+kmaps = []
+
+if len(sys.argv) < 2:
+    print "usage: progname  charmap.kcm [charmap2.kcm ...] > charmap-tab.h"
+else:
+    genline = ""
+    for filepath in sys.argv[1:]:
+        m = re_mapname.match(filepath)
+        if not m:
+            print "%s is not a keyboard charmap name" % filepath
+            os.exit(1)
+
+        mapname = m.group(1)
+        genline = genline + " " + mapname + ".kcm"
+
+    for filepath in sys.argv[1:]:
+        m = re_mapname.match(filepath)
+        mapname = m.group(1)
+        result = process_file( filepath )
+        kmap = KMap(mapname,result)
+        kmaps.append(kmap)
+
+    print header + genline + header2
+    for kmap in kmaps:
+        kmap.dump()
+
+    print "const AKeyCharmap*  android_charmaps[%d] = {" % len(kmaps),
+    comma = ""
+    for kmap in kmaps:
+        print "%s&_%s_charmap" % (comma, kmap.name),
+        comma = ", "
+    print "};"
+    print "const int           android_charmap_count = %d;" % len(kmaps)