#!/usr/bin/python
# -*- python -*-
#
# Keycode Map Generator
#
# Copyright (C) 2009-2017 Red Hat, Inc.
#
# This file is dual license under the terms of the GPLv2 or later
# and 3-clause BSD licenses.
#

# Requires >= 2.6
from __future__ import print_function

import csv
import argparse
import hashlib
import time
import sys

class Database:

    # Linux: linux/input.h
    MAP_LINUX = "linux"

    # OS-X: Carbon/HIToolbox/Events.h
    MAP_OSX = "osx"

    # AT Set 1: linux/drivers/input/keyboard/atkbd.c
    #           (atkbd_set2_keycode + atkbd_unxlate_table)
    MAP_ATSET1 = "atset1"

    # AT Set 2: linux/drivers/input/keyboard/atkbd.c
    #           (atkbd_set2_keycode)
    MAP_ATSET2 = "atset2"

    # AT Set 3: linux/drivers/input/keyboard/atkbd.c
    #           (atkbd_set3_keycode)
    MAP_ATSET3 = "atset3"

    # Linux RAW: linux/drivers/char/keyboard.c (x86_keycodes)
    MAP_XTKBD = "xtkbd"

    # USB HID: linux/drivers/hid/usbhid/usbkbd.c (usb_kbd_keycode)
    MAP_USB = "usb"

    # Win32: mingw32/winuser.h
    MAP_WIN32 = "win32"

    # XWin XT: xorg-server/hw/xwin/{winkeybd.c,winkeynames.h}
    #          (xt + manually transcribed)
    MAP_XWINXT = "xwinxt"

    # X11: http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
    MAP_X11 = "x11"

    # XKBD XT: xf86-input-keyboard/src/at_scancode.c
    #          (xt + manually transcribed)
    MAP_XKBDXT = "xkbdxt"

    # Xorg with evdev: linux + an offset
    MAP_XORGEVDEV = "xorgevdev"

    # Xorg with kbd: xkbdxt + an offset
    MAP_XORGKBD = "xorgkbd"

    # Xorg with OS-X: osx + an offset
    MAP_XORGXQUARTZ = "xorgxquartz"

    # Xorg + Cygwin: xwinxt + an offset
    MAP_XORGXWIN = "xorgxwin"

    # XT over RFB: xtkbd + special re-encoding of high bit
    MAP_RFB = "rfb"

    # HTML codes
    MAP_HTML = "html"

    # XKB key names
    MAP_XKB = "xkb"

    # QEMU keycodes
    MAP_QCODE = "qcode"

    # Sun / Sparc  scan codes
    # Reference: "SPARC International Keyboard Spec 1", page 7 "US scan set"
    MAP_SUN = "sun"

    # Apple Desktop Bus
    # Reference: http://www.archive.org/stream/apple-guide-macintosh-family-hardware/Apple_Guide_to_the_Macintosh_Family_Hardware_2e#page/n345/mode/2up
    MAP_ADB = "adb"

    MAP_LIST = (
        MAP_LINUX,
        MAP_OSX,
        MAP_ATSET1,
        MAP_ATSET2,
        MAP_ATSET3,
        MAP_USB,
        MAP_WIN32,
        MAP_XWINXT,
        MAP_XKBDXT,
        MAP_X11,
        MAP_HTML,
        MAP_XKB,
        MAP_QCODE,
        MAP_SUN,
        MAP_ADB,

        # These are derived from maps above
        MAP_XTKBD,
        MAP_XORGEVDEV,
        MAP_XORGKBD,
        MAP_XORGXQUARTZ,
        MAP_XORGXWIN,
        MAP_RFB,
    )

    CODE_COLUMNS = {
        MAP_LINUX: 1,
        MAP_OSX: 3,
        MAP_ATSET1: 4,
        MAP_ATSET2: 5,
        MAP_ATSET3: 6,
        MAP_USB: 7,
        MAP_WIN32: 9,
        MAP_XWINXT: 10,
        MAP_XKBDXT: 11,
        MAP_X11: 13,
        MAP_HTML: 14,
        MAP_XKB: 15,
        MAP_SUN: 17,
        MAP_ADB: 18,
    }

    ENUM_COLUMNS = {
        MAP_QCODE: 14,
    }

    NAME_COLUMNS = {
        MAP_LINUX: 0,
        MAP_OSX: 2,
        MAP_WIN32: 8,
        MAP_X11: 12,
        MAP_HTML: 14,
        MAP_XKB: 15,
        MAP_QCODE: 16,
    }

    ENUM_BOUND = {
        MAP_QCODE: "Q_KEY_CODE__MAX",
    }

    def __init__(self):

        self.mapto = {}
        self.mapfrom = {}
        self.mapname = {}
        self.mapchecksum = None

        for name in self.MAP_LIST:
            # Key is a MAP_LINUX, value is a MAP_XXX
            self.mapto[name] = {}
            # key is a MAP_XXX, value is a MAP_LINUX
            self.mapfrom[name] = {}

        for name in self.NAME_COLUMNS.keys():
            # key is a MAP_LINUX, value is a string
            self.mapname[name] = {}

    def _generate_checksum(self, filename):
        hash = hashlib.sha256()
        with open(filename, "rb") as f:
            for chunk in iter(lambda: f.read(4096), b""):
                hash.update(chunk)
        self.mapchecksum = hash.hexdigest()

    def load(self, filename):
        self._generate_checksum(filename)

        with open(filename, 'r') as f:
            reader = csv.reader(f)

            first = True

            for row in reader:
                # Discard column headings
                if first:
                    first = False
                    continue

                # We special case MAP_LINUX since that is out
                # master via which all other mappings are done
                linux = self.load_linux(row)

                # Now load all the remaining master data values
                self.load_data(row, linux)

                # Then load all the keycode names
                self.load_names(row, linux)

                # Finally calculate derived key maps
                self.derive_data(row, linux)

    def load_linux(self, row):
        col = self.CODE_COLUMNS[self.MAP_LINUX]
        linux = row[col]

        if linux.startswith("0x"):
            linux = int(linux, 16)
        else:
            linux = int(linux, 10)

        self.mapto[self.MAP_LINUX][linux] = linux
        self.mapfrom[self.MAP_LINUX][linux] = linux

        return linux


    def load_data(self, row, linux):
        for mapname in self.CODE_COLUMNS:
            if mapname == self.MAP_LINUX:
                continue

            col = self.CODE_COLUMNS[mapname]
            val = row[col]

            if val == "":
                continue

            if val.startswith("0x"):
                val = int(val, 16)
            elif val.isdigit():
                val = int(val, 10)

            self.mapto[mapname][linux] = val
            self.mapfrom[mapname][val] = linux

    def load_names(self, row, linux):
        for mapname in self.NAME_COLUMNS:
            col = self.NAME_COLUMNS[mapname]
            val = row[col]

            if val == "":
                continue

            self.mapname[mapname][linux] = val


    def derive_data(self, row, linux):
        # Linux RAW is XT scan codes with special encoding of the
        # 0xe0 scan codes
        if linux in self.mapto[self.MAP_ATSET1]:
            at1 = self.mapto[self.MAP_ATSET1][linux]
            if at1 > 0x7f:
                assert((at1 & ~0x7f) == 0xe000)
                xtkbd = 0x100 | (at1 & 0x7f)
            else:
                xtkbd = at1
            self.mapto[self.MAP_XTKBD][linux] = xtkbd
            self.mapfrom[self.MAP_XTKBD][xtkbd] = linux

        # Xorg KBD is XKBD XT offset by 8
        if linux in self.mapto[self.MAP_XKBDXT]:
            xorgkbd = self.mapto[self.MAP_XKBDXT][linux] + 8
            self.mapto[self.MAP_XORGKBD][linux] = xorgkbd
            self.mapfrom[self.MAP_XORGKBD][xorgkbd] = linux

        # Xorg evdev is Linux offset by 8
        self.mapto[self.MAP_XORGEVDEV][linux] = linux + 8
        self.mapfrom[self.MAP_XORGEVDEV][linux + 8] = linux

        # Xorg XQuartx is OS-X offset by 8
        if linux in self.mapto[self.MAP_OSX]:
            xorgxquartz = self.mapto[self.MAP_OSX][linux] + 8
            self.mapto[self.MAP_XORGXQUARTZ][linux] = xorgxquartz
            self.mapfrom[self.MAP_XORGXQUARTZ][xorgxquartz] = linux

        # Xorg Xwin (aka Cygwin) is XWin XT offset by 8
        if linux in self.mapto[self.MAP_XWINXT]:
            xorgxwin = self.mapto[self.MAP_XWINXT][linux] + 8
            self.mapto[self.MAP_XORGXWIN][linux] = xorgxwin
            self.mapfrom[self.MAP_XORGXWIN][xorgxwin] = linux

        # RFB keycodes are XT scan codes with a slightly
        # different encoding of 0xe0 scan codes
        if linux in self.mapto[self.MAP_ATSET1]:
            at1 = self.mapto[self.MAP_ATSET1][linux]
            if at1 > 0x7f:
                assert((at1 & ~0x7f) == 0xe000)
                rfb = 0x80 | (at1 & 0x7f)
            else:
                rfb = at1
            self.mapto[self.MAP_RFB][linux] = rfb
            self.mapfrom[self.MAP_RFB][rfb] = linux

        if linux in self.mapname[self.MAP_QCODE]:
            qcodeenum = self.mapname[self.MAP_QCODE][linux]
            qcodeenum = "Q_KEY_CODE_" + qcodeenum.upper()
            self.mapto[self.MAP_QCODE][linux] = qcodeenum
            self.mapfrom[self.MAP_QCODE][qcodeenum] = linux

class LanguageGenerator(object):

    def _boilerplate(self, lines):
        raise NotImplementedError()

    def generate_header(self, database, args):
        today = time.strftime("%Y-%m-%d %H:%M")
        self._boilerplate([
            "This file is auto-generated from keymaps.csv on %s" % today,
            "Database checksum sha256(%s)" % database.mapchecksum,
            "To re-generate, run:",
            "  %s" % args,
        ])

class LanguageSrcGenerator(LanguageGenerator):

    TYPE_INT = "integer"
    TYPE_STRING = "string"
    TYPE_ENUM = "enum"

    def _array_start(self, varname, length, defvalue, fromtype, totype):
        raise NotImplementedError()

    def _array_end(self, fromtype, totype):
        raise NotImplementedError()

    def _array_entry(self, index, value, comment, fromtype, totype):
        raise NotImplementedError()

    def generate_code_map(self, varname, database, frommapname, tomapname):
        if frommapname not in database.mapfrom:
            raise Exception("Unknown map %s, expected one of %s" % (
                            frommapname, ", ".join(database.mapfrom.keys())))
        if tomapname not in database.mapto:
            raise Exception("Unknown map %s, expected one of %s" % (
                            tomapname, ", ".join(database.mapto.keys())))

        tolinux = database.mapfrom[frommapname]
        fromlinux = database.mapto[tomapname]

        if varname is None:
            varname = "code_map_%s_to_%s" % (frommapname, tomapname)

        if frommapname in database.ENUM_COLUMNS:
            fromtype = self.TYPE_ENUM
        elif type(tolinux.keys()[0]) == str:
            fromtype = self.TYPE_STRING
        else:
            fromtype = self.TYPE_INT

        if tomapname in database.ENUM_COLUMNS:
            totype = self.TYPE_ENUM
        elif type(fromlinux.values()[0]) == str:
            totype = self.TYPE_STRING
        else:
            totype = self.TYPE_INT

        keys = tolinux.keys()
        keys.sort()
        if fromtype == self.TYPE_INT:
            keys = range(keys[-1] + 1)

        if fromtype == self.TYPE_ENUM:
            keymax = database.ENUM_BOUND[frommapname]
        else:
            keymax = len(keys)

        defvalue = fromlinux.get(0, None)
        if fromtype == self.TYPE_ENUM:
            self._array_start(varname, keymax, defvalue, fromtype, totype)
        else:
            self._array_start(varname, keymax, None, fromtype, totype)

        for src in keys:
            linux = tolinux.get(src, None)
            if linux is None:
                dst = None
            else:
                dst = fromlinux.get(linux, defvalue)

            comment = "%s -> %s -> %s" % (self._label(database, frommapname, src, linux),
                                          self._label(database, Database.MAP_LINUX, linux, linux),
                                          self._label(database, tomapname, dst, linux))
            self._array_entry(src, dst, comment, fromtype, totype)
        self._array_end(fromtype, totype)

    def generate_code_table(self, varname, database, mapname):
        if mapname not in database.mapto:
            raise Exception("Unknown map %s, expected one of %s" % (
                            mapname, ", ".join(database.mapto.keys())))

        keys = database.mapto[Database.MAP_LINUX].keys()
        keys.sort()
        names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for key in keys]

        if varname is None:
            varname = "code_table_%s" % mapname

        if mapname in database.ENUM_COLUMNS:
            totype = self.TYPE_ENUM
        elif type(database.mapto[mapname].values()[0]) == str:
            totype = self.TYPE_STRING
        else:
            totype = self.TYPE_INT

        self._array_start(varname, len(keys), None, self.TYPE_INT, totype)

        defvalue = database.mapto[mapname].get(0, None)
        for i in range(len(keys)):
            key = keys[i]
            dst = database.mapto[mapname].get(key, defvalue)
            self._array_entry(i, dst, names[i], self.TYPE_INT, totype)

        self._array_end(self.TYPE_INT, totype)

    def generate_name_map(self, varname, database, frommapname, tomapname):
        if frommapname not in database.mapfrom:
            raise Exception("Unknown map %s, expected one of %s" % (
                            frommapname, ", ".join(database.mapfrom.keys())))
        if tomapname not in database.mapname:
            raise Exception("Unknown map %s, expected one of %s" % (
                            tomapname, ", ".join(database.mapname.keys())))

        tolinux = database.mapfrom[frommapname]
        fromlinux = database.mapname[tomapname]

        if varname is None:
            varname = "name_map_%s_to_%s" % (frommapname, tomapname)

        keys = tolinux.keys()
        keys.sort()
        if type(keys[0]) == int:
            keys = range(keys[-1] + 1)

        if type(keys[0]) == int:
            fromtype = self.TYPE_INT
        else:
            fromtype = self.TYPE_STRING

        self._array_start(varname, len(keys), None, fromtype, self.TYPE_STRING)

        for src in keys:
            linux = tolinux.get(src, None)
            if linux is None:
                dst = None
            else:
                dst = fromlinux.get(linux, None)

            comment = "%s -> %s -> %s" % (self._label(database, frommapname, src, linux),
                                          self._label(database, Database.MAP_LINUX, linux, linux),
                                          self._label(database, tomapname, dst, linux))
            self._array_entry(src, dst, comment, fromtype, self.TYPE_STRING)
        self._array_end(fromtype, self.TYPE_STRING)

    def generate_name_table(self, varname, database, mapname):
        if mapname not in database.mapname:
            raise Exception("Unknown map %s, expected one of %s" % (
                            mapname, ", ".join(database.mapname.keys())))

        keys = database.mapto[Database.MAP_LINUX].keys()
        keys.sort()
        names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for key in keys]

        if varname is None:
            varname = "name_table_%s" % mapname

        self._array_start(varname, len(keys), None, self.TYPE_INT, self.TYPE_STRING)

        for i in range(len(keys)):
            key = keys[i]
            dst = database.mapname[mapname].get(key, None)
            self._array_entry(i, dst, names[i], self.TYPE_INT, self.TYPE_STRING)

        self._array_end(self.TYPE_INT, self.TYPE_STRING)

    def _label(self, database, mapname, val, linux):
        if mapname in database.mapname:
            return "%s:%s (%s)" % (mapname, val, database.mapname[mapname].get(linux, "unnamed"))
        else:
            return "%s:%s" % (mapname, val)

class LanguageDocGenerator(LanguageGenerator):

    def _array_start_name_doc(self, varname, namemap):
        raise NotImplementedError()

    def _array_start_code_doc(self, varname, namemap, codemap):
        raise NotImplementedError()

    def _array_end(self):
        raise NotImplementedError()

    def _array_name_entry(self, value, name):
        raise NotImplementedError()

    def _array_code_entry(self, value, name):
        raise NotImplementedError()

    def generate_name_docs(self, varname, database, mapname):
        if mapname not in database.mapname:
            raise Exception("Unknown map %s, expected one of %s" % (
                            mapname, ", ".join(database.mapname.keys())))

        keys = database.mapto[Database.MAP_LINUX].keys()
        keys.sort()
        names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for key in keys]

        if varname is None:
            varname = mapname

        self._array_start_name_doc(varname, mapname)

        for i in range(len(keys)):
            key = keys[i]
            dst = database.mapname[mapname].get(key, None)
            self._array_name_entry(key, dst)

        self._array_end()


    def generate_code_docs(self, varname, database, mapname):
        if mapname not in database.mapfrom:
            raise Exception("Unknown map %s, expected one of %s" % (
                            mapname, ", ".join(database.mapfrom.keys())))

        tolinux = database.mapfrom[mapname]
        keys = tolinux.keys()
        keys.sort()
        if mapname in database.mapname:
            names = database.mapname[mapname]
            namemap = mapname
        else:
            names = database.mapname[Database.MAP_LINUX]
            namemap = Database.MAP_LINUX

        if varname is None:
            varname = mapname

        self._array_start_code_doc(varname, mapname, namemap)

        for i in range(len(keys)):
            key = keys[i]
            self._array_code_entry(key, names.get(tolinux[key], "unnamed"))

        self._array_end()

class CLanguageGenerator(LanguageSrcGenerator):

    def __init__(self, inttypename, strtypename, lentypename):
        self.inttypename = inttypename
        self.strtypename = strtypename
        self.lentypename = lentypename

    def _boilerplate(self, lines):
        print("/*")
        for line in lines:
            print(" * %s" % line)
        print("*/")

    def _array_start(self, varname, length, defvalue, fromtype, totype):
        self._varname = varname;
        totypename = self.strtypename if totype == self.TYPE_STRING else self.inttypename
        if fromtype in (self.TYPE_INT, self.TYPE_ENUM):
            if type(length) == str:
                print("const %s %s[%s] = {" % (totypename, varname, length))
            else:
                print("const %s %s[%d] = {" % (totypename, varname, length))
        else:
            print("const struct _%s {" % varname)
            print("  const %s from;" % self.strtypename)
            print("  const %s to;" % totypename)
            print("} %s[] = {" % varname)

        if defvalue != None:
            if totype == self.TYPE_ENUM:
                if type(length) == str:
                    print("  [0 ... %s-1] = %s," % (length, defvalue))
                else:
                    print("  [0 ... 0x%x-1] = %s," % (length, defvalue))
            else:
                if type(length) == str:
                    print("  [0 ... %s-1] = 0x%x," % (length, defvalue))
                else:
                    print("  [0 ... 0x%x-1] = 0x%x," % (length, defvalue))

    def _array_end(self, fromtype, totype):
        print("};")
        print("const %s %s_len = sizeof(%s)/sizeof(%s[0]);" %
              (self.lentypename, self._varname, self._varname, self._varname))

    def _array_entry(self, index, value, comment, fromtype, totype):
        if value is None:
            return
        if fromtype == self.TYPE_INT:
            indexfmt = "0x%x"
        elif fromtype == self.TYPE_ENUM:
            indexfmt = "%s"
        else:
            indexfmt = "\"%s\""

        if totype == self.TYPE_INT:
            valuefmt = "0x%x"
        elif totype == self.TYPE_ENUM:
            valuefmt = "%s"
        else:
            valuefmt = "\"%s\""

        if fromtype != self.TYPE_STRING:
            print(("  [" + indexfmt + "] = " + valuefmt + ", /* %s */") % (index, value, comment))
        else:
            print(("  {" + indexfmt + ", " + valuefmt + "}, /* %s */") % (index, value, comment))

class CppLanguageGenerator(CLanguageGenerator):

    def _array_start(self, varname, length, defvalue, fromtype, totype):
        if fromtype == self.TYPE_ENUM:
            raise NotImplementedError("Enums not supported as source in C++ generator")
        totypename = "const " + self.strtypename if totype == self.TYPE_STRING else self.inttypename
        if fromtype == self.TYPE_INT:
            print("#include <vector>")
            print("const std::vector<%s> %s = {" % (totypename, varname))
        else:
            print("#include <map>")
            print("#include <string>")
            print("const std::map<const std::string, %s> %s = {" % (totypename, varname))

    def _array_end(self, fromtype, totype):
        print("};")

    # designated initializers not available in C++
    def _array_entry(self, index, value, comment, fromtype, totype):
        if fromtype == self.TYPE_STRING:
            return super(CppLanguageGenerator, self)._array_entry(index, value, comment, fromtype, totype)

        if value is None:
            print("  0, /* %s */" % comment)
        elif totype == self.TYPE_INT:
            print("  0x%x, /* %s */" % (value, comment))
        elif totype == self.TYPE_ENUM:
            print("  %s, /* %s */" % (value, comment))
        else:
            print("  \"%s\", /* %s */" % (value, comment))

class StdCLanguageGenerator(CLanguageGenerator):

    def __init__(self):
        super(StdCLanguageGenerator, self).__init__("unsigned short", "char *", "unsigned int")

class StdCppLanguageGenerator(CppLanguageGenerator):

    def __init__(self):
        super(StdCppLanguageGenerator, self).__init__("unsigned short", "char *", "unsigned int")

class GLib2LanguageGenerator(CLanguageGenerator):

    def __init__(self):
        super(GLib2LanguageGenerator, self).__init__("guint16", "gchar *", "guint")

class PythonLanguageGenerator(LanguageSrcGenerator):

    def _boilerplate(self, lines):
        print("#")
        for line in lines:
            print("# %s" % line)
        print("#")

    def _array_start(self, varname, length, defvalue, fromtype, totype):
        if fromtype == self.TYPE_ENUM:
            raise NotImplementedError("Enums not supported as source in Python generator")

        if fromtype != self.TYPE_STRING:
            print("%s = [" % varname)
        else:
            print("%s = {" % varname)

    def _array_end(self, fromtype, totype):
        if fromtype != self.TYPE_STRING:
            print("]")
        else:
            print("}")

    def _array_entry(self, index, value, comment, fromtype, totype):
        if fromtype == self.TYPE_INT:
            if value is None:
                print("  None, # %s" % (comment))
            elif totype == self.TYPE_INT:
                print("  0x%x, # %s" % (value, comment))
            elif totype == self.TYPE_ENUM:
                print("  %s, # %s" % (value, comment))
            else:
                print("  \"%s\", # %s" % (value, comment))
        else:
            if value is None:
                print("  \"%s\": None, # %s" % (index, comment))
            elif totype == self.TYPE_INT:
                print("  \"%s\": 0x%x, # %s" % (index, value, comment))
            elif totype == self.TYPE_ENUM:
                print("  \"%s\": %s, # %s" % (index, value, comment))
            else:
                print("  \"%s\": \"%s\", # %s" % (index, value, comment))

class PerlLanguageGenerator(LanguageSrcGenerator):

    def _boilerplate(self, lines):
        print("#")
        for line in lines:
            print("# %s" % line)
        print("#")

    def _array_start(self, varname, length, defvalue, fromtype, totype):
        if fromtype == self.TYPE_ENUN:
            raise NotImplementedError("Enums not supported as source in Python generator")
        if fromtype == self.TYPE_INT:
            print("my @%s = (" % varname)
        else:
            print("my %%%s = (" % varname)

    def _array_end(self, fromtype, totype):
        print(");")

    def _array_entry(self, index, value, comment, fromtype, totype):
        if fromtype == self.TYPE_INT:
            if value is None:
                print("  undef, # %s" % (comment))
            elif totype == self.TYPE_INT:
                print("  0x%x, # %s" % (value, comment))
            elif totype == self.TYPE_ENUM:
                print("  %s, # %s" % (value, comment))
            else:
                print("  \"%s\", # %s" % (value, comment))
        else:
            if value is None:
                print("  \"%s\", undef, # %s" % (index, comment))
            elif totype == self.TYPE_INT:
                print("  \"%s\", 0x%x, # %s" % (index, value, comment))
            elif totype == self.TYPE_ENUM:
                print("  \"%s\", 0x%x, # %s" % (index, value, comment))
            else:
                print("  \"%s\", \"%s\", # %s" % (index, value, comment))

class JavaScriptLanguageGenerator(LanguageSrcGenerator):

    def _boilerplate(self, lines):
        print("/*")
        for line in lines:
            print(" * %s" % line)
        print("*/")

    def _array_start(self, varname, length, defvalue, fromtype, totype):
        print("export default {")

    def _array_end(self, fromtype, totype):
        print("};")

    def _array_entry(self, index, value, comment, fromtype, totype):
        if value is None:
            return

        if fromtype == self.TYPE_INT:
            fromfmt = "0x%x"
        elif fromtype == self.TYPE_ENUM:
            fromfmt = "%s"
        else:
            fromfmt = "\"%s\""

        if totype == self.TYPE_INT:
            tofmt = "0x%x"
        elif totype == self.TYPE_ENUM:
            tofmt = "%s"
        else:
            tofmt = "\"%s\""

        print(("  " + fromfmt + ": " + tofmt + ", /* %s */") % (index, value, comment))

class PodLanguageGenerator(LanguageDocGenerator):

    def _boilerplate(self, lines):
        print("#")
        for line in lines:
            print("# %s" % line)
        print("#")

    def _array_start_name_doc(self, varname, namemap):
        print("=head1 %s" % varname)
        print("")
        print("List of %s key code names, with corresponding key code values" % namemap)
        print("")
        print("=over 4")
        print("")

    def _array_start_code_doc(self, varname, codemap, namemap):
        print("=head1 %s" % varname)
        print("")
        print("List of %s key code values, with corresponding %s key code names" % (codemap, namemap))
        print("")
        print("=over 4")
        print("")

    def _array_end(self):
        print("=back")
        print("")

    def _array_name_entry(self, value, name):
        print("=item %s" % name)
        print("")
        print("Key value %d (0x%x)" % (value, value))
        print("")

    def _array_code_entry(self, value, name):
        print("=item %d (0x%x)" % (value, value))
        print("")
        print("Key name %s" % name)
        print("")

SRC_GENERATORS = {
    "stdc": StdCLanguageGenerator(),
    "stdc++": StdCppLanguageGenerator(),
    "glib2": GLib2LanguageGenerator(),
    "python2": PythonLanguageGenerator(),
    "python3": PythonLanguageGenerator(),
    "perl": PerlLanguageGenerator(),
    "js": JavaScriptLanguageGenerator(),
}
DOC_GENERATORS = {
    "pod": PodLanguageGenerator(),
}

def code_map(args):
    database = Database()
    database.load(args.keymaps)

    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["code-map", "keymaps.csv", args.frommapname, args.tomapname])
    SRC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    SRC_GENERATORS[args.lang].generate_code_map(args.varname, database, args.frommapname, args.tomapname)

def code_table(args):
    database = Database()
    database.load(args.keymaps)

    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["code-table", "keymaps.csv", args.mapname])
    SRC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    SRC_GENERATORS[args.lang].generate_code_table(args.varname, database, args.mapname)

def name_map(args):
    database = Database()
    database.load(args.keymaps)

    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["name-map", "keymaps.csv", args.frommapname, args.tomapname])
    SRC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    SRC_GENERATORS[args.lang].generate_name_map(args.varname, database, args.frommapname, args.tomapname)

def name_table(args):
    database = Database()
    database.load(args.keymaps)


    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["name-table", "keymaps.csv", args.mapname])
    SRC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    SRC_GENERATORS[args.lang].generate_name_table(args.varname, database, args.mapname)

def code_docs(args):
    database = Database()
    database.load(args.keymaps)


    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["code-docs", "keymaps.csv", args.mapname])
    DOC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    DOC_GENERATORS[args.lang].generate_code_docs(args.varname, database, args.mapname)

def name_docs(args):
    database = Database()
    database.load(args.keymaps)


    cliargs = ["keymap-gen", "--lang=%s" % args.lang]
    if args.varname is not None:
        cliargs.append("--varname=%s" % args.varname)
    cliargs.extend(["name-docs", "keymaps.csv", args.mapname])
    DOC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))

    DOC_GENERATORS[args.lang].generate_name_docs(args.varname, database, args.mapname)

def usage():
    print ("Please select a command:")
    print ("  'code-map', 'code-table', 'name-map', 'name-table', 'docs'")
    sys.exit(1)

def main():
    parser = argparse.ArgumentParser()

    parser.add_argument("--lang", default="stdc",
                        help="Output language, (src=%s, doc=%s)" % (
                            ",".join(SRC_GENERATORS.keys()),
                            ",".join(DOC_GENERATORS.keys())))
    parser.add_argument("--varname", default=None,
                        help="Data variable name")

    subparsers = parser.add_subparsers(help="sub-command help")

    codemapparser = subparsers.add_parser("code-map", help="Generate a mapping between code tables")
    codemapparser.add_argument("keymaps", help="Path to keymap CSV data file")
    codemapparser.add_argument("frommapname", help="Source code table name")
    codemapparser.add_argument("tomapname", help="Target code table name")
    codemapparser.set_defaults(func=code_map)

    codetableparser = subparsers.add_parser("code-table", help="Generate a flat code table")
    codetableparser.add_argument("keymaps", help="Path to keymap CSV data file")
    codetableparser.add_argument("mapname", help="Code table name")
    codetableparser.set_defaults(func=code_table)

    namemapparser = subparsers.add_parser("name-map", help="Generate a mapping to names")
    namemapparser.add_argument("keymaps", help="Path to keymap CSV data file")
    namemapparser.add_argument("frommapname", help="Source code table name")
    namemapparser.add_argument("tomapname", help="Target name table name")
    namemapparser.set_defaults(func=name_map)

    nametableparser = subparsers.add_parser("name-table", help="Generate a flat name table")
    nametableparser.add_argument("keymaps", help="Path to keymap CSV data file")
    nametableparser.add_argument("mapname", help="Name table name")
    nametableparser.set_defaults(func=name_table)

    codedocsparser = subparsers.add_parser("code-docs", help="Generate code documentation")
    codedocsparser.add_argument("keymaps", help="Path to keymap CSV data file")
    codedocsparser.add_argument("mapname", help="Code table name")
    codedocsparser.set_defaults(func=code_docs)

    namedocsparser = subparsers.add_parser("name-docs", help="Generate name documentation")
    namedocsparser.add_argument("keymaps", help="Path to keymap CSV data file")
    namedocsparser.add_argument("mapname", help="Name table name")
    namedocsparser.set_defaults(func=name_docs)

    args = parser.parse_args()
    if hasattr(args, "func"):
        args.func(args)
    else:
        usage()


main()
