Home | History | Annotate | Download | only in qemu
      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 #
      8 import sys, os, string, re
      9 
     10 header = """\
     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 
     18 header2 = """
     19  */
     20 """
     21 
     22 kmap_header = """\
     23 static const AKeyEntry  _%(name)s_keys[] =
     24 {
     25    /* keycode                   base   caps    fn  caps+fn   number */
     26 """
     27 
     28 
     29 kmap_footer = """\
     30 };
     31 
     32 static const AKeyCharmap  _%(name)s_charmap =
     33 {
     34     _%(name)s_keys,
     35     %(count)d,
     36     "%(name)s"
     37 };
     38 """
     39 
     40 
     41 re_mapname = re.compile( r".*/(\w+).kcm" )
     42 re_start = re.compile( r"(\w+)\s*(.*)" )
     43 re_char  = re.compile( r"('.')\s*(.*)" )
     44 re_hex   = re.compile( r"(0x\w+)\s*(.*)" )
     45 
     46 specials = { '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 
     67 entries = []
     68 
     69 def 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 
     75 def quote(s):
     76     if s == "'''":
     77         s = "'\\''"
     78     elif s == "'\\'":
     79         s = "'\\\\'"
     80     return s
     81 
     82 def 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 
    132 def 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 
    146 class 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 
    158 kmaps = []
    159 
    160 if len(sys.argv) < 2:
    161     print "usage: progname  charmap.kcm [charmap2.kcm ...] > charmap-tab.h"
    162 else:
    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