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