#!/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': 'Newline',
'TAB': 'Tab',
'STAR': 'Star',
'POUND': 'Pound',
'PLUS': 'Plus',
'DEL': 'Del'
}
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
disp = 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))
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))
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)