blob: 418201b1221f606c3b77b18bddff16010ddded2c [file] [log] [blame]
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -08001#!/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',
vchtchetkine9085a282009-09-14 15:29:20 -070059 'ENTER': 'Newline',
60 'TAB': 'Tab',
61 'STAR': 'Star',
62 'POUND': 'Pound',
63 'PLUS': 'Plus',
64 'DEL': 'Del'
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -080065 }
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
vchtchetkine9085a282009-09-14 15:29:20 -070093 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
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800105 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))
The Android Open Source Project8b23a6c2009-03-03 19:30:32 -0800124
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)