#!/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)