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

    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,

        # 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,
    }

    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,
    }

    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, 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 = None
        else:
            keymax = len(keys)

        self._array_start(varname, keymax, fromtype, totype)

        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, 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), self.TYPE_INT, totype)

        for i in range(len(keys)):
            key = keys[i]
            dst = database.mapto[mapname].get(key, None)
            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), 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), 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):
        self.inttypename = inttypename
        self.strtypename = strtypename

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

    def _array_start(self, varname, length, 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 length is None:
                print("const %s %s[] = {" % (totypename, varname))
            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)

    def _array_end(self, fromtype, totype):
        print("};")
        print("const unsigned int %s_len = sizeof(%s)/sizeof(%s[0]);" %
              (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, 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 *")

class StdCppLanguageGenerator(CppLanguageGenerator):

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

class GLib2LanguageGenerator(CLanguageGenerator):

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

class PythonLanguageGenerator(LanguageSrcGenerator):

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

    def _array_start(self, varname, length, 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, 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, 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()
