| 
									
										
										
										
											2018-02-22 14:34:57 +03:00
										 |  |  | #!/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 | 
					
						
							|  |  |  | try: | 
					
						
							|  |  |  |     import argparse | 
					
						
							|  |  |  | except: | 
					
						
							|  |  |  |     import os, sys | 
					
						
							|  |  |  |     sys.path.append(os.path.join(os.path.dirname(__file__), "../thirdparty")) | 
					
						
							|  |  |  |     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" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # QEMU key numbers: xtkbd + special re-encoding of high bit | 
					
						
							|  |  |  |     MAP_QNUM = "qnum" | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # 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_QNUM, | 
					
						
							|  |  |  |     ) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         # QNUM 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) | 
					
						
							|  |  |  |                 qnum = 0x80 | (at1 & 0x7f) | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 qnum = at1 | 
					
						
							|  |  |  |             self.mapto[self.MAP_QNUM][linux] = qnum | 
					
						
							|  |  |  |             self.mapfrom[self.MAP_QNUM][qnum] = linux | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             # Hack for compatibility with previous mistakes in handling | 
					
						
							|  |  |  |             # Print/SysRq. The preferred qnum for Print/SysRq is 0x54, | 
					
						
							|  |  |  |             # but QEMU previously allowed 0xb7 too | 
					
						
							|  |  |  |             if qnum == 0x54: | 
					
						
							|  |  |  |                 self.mapfrom[self.MAP_QNUM][0xb7] = self.mapfrom[self.MAP_QNUM][0x54] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         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 | 
					
						
							| 
									
										
										
										
											2018-08-30 16:00:07 +03:00
										 |  |  |         elif type(list(tolinux.keys())[0]) == str: | 
					
						
							| 
									
										
										
										
											2018-02-22 14:34:57 +03:00
										 |  |  |             fromtype = self.TYPE_STRING | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             fromtype = self.TYPE_INT | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if tomapname in database.ENUM_COLUMNS: | 
					
						
							|  |  |  |             totype = self.TYPE_ENUM | 
					
						
							| 
									
										
										
										
											2018-08-30 16:00:07 +03:00
										 |  |  |         elif type(list(fromlinux.values())[0]) == str: | 
					
						
							| 
									
										
										
										
											2018-02-22 14:34:57 +03:00
										 |  |  |             totype = self.TYPE_STRING | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             totype = self.TYPE_INT | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-30 16:00:07 +03:00
										 |  |  |         keys = list(tolinux.keys()) | 
					
						
							| 
									
										
										
										
											2018-02-22 14:34:57 +03:00
										 |  |  |         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()))) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-30 16:00:07 +03:00
										 |  |  |         keys = list(database.mapto[Database.MAP_LINUX].keys()) | 
					
						
							| 
									
										
										
										
											2018-02-22 14:34:57 +03:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											2018-08-30 16:00:07 +03:00
										 |  |  |         elif type(list(database.mapto[mapname].values())[0]) == str: | 
					
						
							| 
									
										
										
										
											2018-02-22 14:34:57 +03:00
										 |  |  |             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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-30 16:00:07 +03:00
										 |  |  |         keys = list(tolinux.keys()) | 
					
						
							| 
									
										
										
										
											2018-02-22 14:34:57 +03:00
										 |  |  |         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()))) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-30 16:00:07 +03:00
										 |  |  |         keys = list(database.mapto[Database.MAP_LINUX].keys()) | 
					
						
							| 
									
										
										
										
											2018-02-22 14:34:57 +03:00
										 |  |  |         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()))) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-08-30 16:00:07 +03:00
										 |  |  |         keys = list(database.mapto[Database.MAP_LINUX].keys()) | 
					
						
							| 
									
										
										
										
											2018-02-22 14:34:57 +03:00
										 |  |  |         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] | 
					
						
							| 
									
										
										
										
											2018-08-30 16:00:07 +03:00
										 |  |  |         keys = list(tolinux.keys()) | 
					
						
							| 
									
										
										
										
											2018-02-22 14:34:57 +03:00
										 |  |  |         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() |