1#!/usr/bin/python 2# 3# a python script used to generate some C constant tables from a key charmap file 4# 5# usage: 6# progname file.kcm > charmap-tab.h 7# 8import sys, os, string, re 9 10header = """\ 11#include "android_charmap.h" 12 13/* the following is automatically generated by the 'gen-charmap.py' script 14 * do not touch. the generation command was: 15 * gen-charmap.py\ 16""" 17 18header2 = """ 19 */ 20""" 21 22kmap_header = """\ 23static const AKeyEntry _%(name)s_keys[] = 24{ 25 /* keycode base caps fn caps+fn number */ 26""" 27 28 29kmap_footer = """\ 30}; 31 32static const AKeyCharmap _%(name)s_charmap = 33{ 34 _%(name)s_keys, 35 %(count)d, 36 "%(name)s" 37}; 38""" 39 40 41re_mapname = re.compile( r".*/(\w+).kcm" ) 42re_start = re.compile( r"(\w+)\s*(.*)" ) 43re_char = re.compile( r"('.')\s*(.*)" ) 44re_hex = re.compile( r"(0x\w+)\s*(.*)" ) 45 46specials = { 'COMMA': 'Comma', 47 'PERIOD': 'Period', 48 'AT': 'At', 49 'LEFT_BRACKET': 'LeftBracket', 50 'RIGHT_BRACKET': 'RightBracket', 51 'SLASH': 'Slash', 52 'BACKSLASH': 'Backslash', 53 'GRAVE': 'Grave', 54 'MINUS': 'Minus', 55 'EQUALS': 'Equals', 56 'SEMICOLON': 'Semicolon', 57 'APOSTROPHE': 'Apostrophe', 58 'SPACE': 'Space', 59 'ENTER': 'Newline', 60 'TAB': 'Tab', 61 'STAR': 'Star', 62 'POUND': 'Pound', 63 'PLUS': 'Plus', 64 'DEL': 'Del' 65 } 66 67entries = [] 68 69def match_char_or_hex(line): 70 m = re_char.match(line) 71 if not m: 72 m = re_hex.match(line) 73 return m 74 75def quote(s): 76 if s == "'''": 77 s = "'\\''" 78 elif s == "'\\'": 79 s = "'\\\\'" 80 return s 81 82def process_line(line,result): 83 m = re_start.match(line) 84 if not m: 85 print "bad bad line: " + line 86 return -1 87 keycode = m.group(1) 88 line = m.group(2) 89 m = match_char_or_hex(line) 90 if not m: 91 print "character expected in: " + line 92 return -1 93 disp = quote(m.group(1)) 94 line = m.group(2) 95 m = match_char_or_hex(line) 96 if not m: 97 print "character expected in: " + line 98 return -1 99 number = quote(m.group(1)) 100 line = m.group(2) 101 m = match_char_or_hex(line) 102 if not m: 103 print "character expected in: " + line 104 return -1 105 base = quote(m.group(1)) 106 line = m.group(2) 107 m = match_char_or_hex(line) 108 if not m: 109 print "character expected in: " + line 110 return -1 111 caps = quote(m.group(1)) 112 line = m.group(2) 113 m = match_char_or_hex(line) 114 if not m: 115 print "character expected in: " + line 116 return -1 117 fn = quote(m.group(1)) 118 line = m.group(2) 119 m = match_char_or_hex(line) 120 if not m: 121 print "character expected in: " + line 122 return -1 123 caps_fn = quote(m.group(1)) 124 125 if specials.has_key(keycode): 126 keycode = specials[keycode] 127 keycode = "kKeyCode" + keycode 128 129 result.append( (keycode,base,caps,fn,caps_fn,number) ) 130 return 0 131 132def process_file( file ): 133 result = [] 134 fp = open(file,"rb") 135 for line in fp.xreadlines(): 136 line = line.strip() 137 if not line: # skip empty lines 138 continue 139 if line[0] == '#' or line[0] == '[': # skip 140 continue 141 if process_line(line,result) < 0: 142 break 143 fp.close() 144 return result 145 146class KMap: 147 def __init__(self,name,results): 148 self.name = name 149 self.results = results 150 151 def dump(self): 152 t = { 'name': self.name, 'count':len(self.results) } 153 print kmap_header % t 154 for item in self.results: 155 print " { %-22s, %5s, %5s, %5s, %6s, %5s }," % item 156 print kmap_footer % t 157 158kmaps = [] 159 160if len(sys.argv) < 2: 161 print "usage: progname charmap.kcm [charmap2.kcm ...] > charmap-tab.h" 162else: 163 genline = "" 164 for filepath in sys.argv[1:]: 165 m = re_mapname.match(filepath) 166 if not m: 167 print "%s is not a keyboard charmap name" % filepath 168 os.exit(1) 169 170 mapname = m.group(1) 171 genline = genline + " " + mapname + ".kcm" 172 173 for filepath in sys.argv[1:]: 174 m = re_mapname.match(filepath) 175 mapname = m.group(1) 176 result = process_file( filepath ) 177 kmap = KMap(mapname,result) 178 kmaps.append(kmap) 179 180 print header + genline + header2 181 for kmap in kmaps: 182 kmap.dump() 183 184 print "const AKeyCharmap* android_charmaps[%d] = {" % len(kmaps), 185 comma = "" 186 for kmap in kmaps: 187 print "%s&_%s_charmap" % (comma, kmap.name), 188 comma = ", " 189 print "};" 190 print "const int android_charmap_count = %d;" % len(kmaps) 191