[pve-devel] [PATCH qemu 3/7] buildsys: use QEMU's keycodemapdb again
Fiona Ebner
f.ebner at proxmox.com
Thu Sep 28 14:59:22 CEST 2023
instead of the split-out version that was last updated for QEMU 6.0.
This reverts the relevant part of 6838f03 ("bump version to 2.11.1-1")
which doesn't state a reason why the splitting was done. If something
breaks, we can still re-do it and document the reason this time.
Alternatively, it would be necessary to adapt the paths, because
keycodemapdb lives in subprojects/ rather than ui/ since QEMU commit
c53648abba ("meson: use subproject for keycodemapdb").
Signed-off-by: Fiona Ebner <f.ebner at proxmox.com>
---
Makefile | 15 +-
keycodemapdb/LICENSE.BSD | 27 -
keycodemapdb/LICENSE.GPL2 | 339 ---
keycodemapdb/README | 114 -
keycodemapdb/data/README | 89 -
keycodemapdb/data/keymaps.csv | 539 ----
keycodemapdb/meson.build | 1 -
keycodemapdb/tests/.gitignore | 11 -
keycodemapdb/tests/Makefile | 150 --
keycodemapdb/tests/javascript | 53 -
keycodemapdb/tests/python2 | 3 -
keycodemapdb/tests/python3 | 3 -
keycodemapdb/tests/stdc++.cc | 40 -
keycodemapdb/tests/stdc.c | 64 -
keycodemapdb/tests/test.py | 30 -
keycodemapdb/thirdparty/LICENSE-argparse.txt | 20 -
keycodemapdb/thirdparty/__init__.py | 0
keycodemapdb/thirdparty/argparse.py | 2392 ------------------
keycodemapdb/tools/keymap-gen | 1147 ---------
19 files changed, 1 insertion(+), 5036 deletions(-)
delete mode 100644 keycodemapdb/LICENSE.BSD
delete mode 100644 keycodemapdb/LICENSE.GPL2
delete mode 100644 keycodemapdb/README
delete mode 100644 keycodemapdb/data/README
delete mode 100644 keycodemapdb/data/keymaps.csv
delete mode 100644 keycodemapdb/meson.build
delete mode 100644 keycodemapdb/tests/.gitignore
delete mode 100644 keycodemapdb/tests/Makefile
delete mode 100755 keycodemapdb/tests/javascript
delete mode 100755 keycodemapdb/tests/python2
delete mode 100755 keycodemapdb/tests/python3
delete mode 100644 keycodemapdb/tests/stdc++.cc
delete mode 100644 keycodemapdb/tests/stdc.c
delete mode 100644 keycodemapdb/tests/test.py
delete mode 100644 keycodemapdb/thirdparty/LICENSE-argparse.txt
delete mode 100644 keycodemapdb/thirdparty/__init__.py
delete mode 100644 keycodemapdb/thirdparty/argparse.py
delete mode 100755 keycodemapdb/tools/keymap-gen
diff --git a/Makefile b/Makefile
index e389a9c..cad130e 100644
--- a/Makefile
+++ b/Makefile
@@ -39,16 +39,14 @@ PC_BIOS_FW_PURGE_LIST_IN = \
BLOB_PURGE_SED_CMDS = $(foreach FILE,$(PC_BIOS_FW_PURGE_LIST_IN),-e "/$(FILE)/d")
BLOB_PURGE_FILTER = $(foreach FILE,$(PC_BIOS_FW_PURGE_LIST_IN),-e "$(FILE)")
-$(BUILDDIR): keycodemapdb | submodule
+$(BUILDDIR): submodule
# check if qemu/ was used for a build
# if so, please run 'make distclean' in the submodule and try again
test ! -f $(SRCDIR)/build/config.status
rm -rf $@.tmp $@
cp -a $(SRCDIR) $@.tmp
cp -a debian $@.tmp/debian
- rm -rf $@.tmp/ui/keycodemapdb
rm -rf $@.tmp/roms/edk2 # packaged separately
- cp -a keycodemapdb $@.tmp/ui/
find $@.tmp/pc-bios -type f | grep $(BLOB_PURGE_FILTER) | xargs rm -f
sed -i $(BLOB_PURGE_SED_CMDS) $@.tmp/pc-bios/meson.build
echo "git clone git://git.proxmox.com/git/pve-qemu.git\\ngit checkout $(GITVERSION)" > $@.tmp/debian/SOURCE
@@ -76,17 +74,6 @@ dsc:
$(DSC): $(ORIG_SRC_TAR) $(BUILDDIR)
cd $(BUILDDIR); dpkg-buildpackage -S -us -uc -d
-.PHONY: update
-update:
- cd $(SRCDIR) && git submodule deinit ui/keycodemapdb || true
- rm -rf $(SRCDIR)/ui/keycodemapdb
- mkdir $(SRCDIR)/ui/keycodemapdb
- cd $(SRCDIR) && git submodule update --init ui/keycodemapdb
- rm -rf keycodemapdb
- mkdir keycodemapdb
- cp -R $(SRCDIR)/ui/keycodemapdb/* keycodemapdb/
- git add keycodemapdb
-
.PHONY: upload
upload: UPLOAD_DIST ?= $(DEB_DISTRIBUTION)
upload: $(DEBS)
diff --git a/keycodemapdb/LICENSE.BSD b/keycodemapdb/LICENSE.BSD
deleted file mode 100644
index ec1a29d..0000000
--- a/keycodemapdb/LICENSE.BSD
+++ /dev/null
@@ -1,27 +0,0 @@
-Copyright (c) Individual contributors.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- 3. Neither the name of PyCA Cryptography nor the names of its contributors
- may be used to endorse or promote products derived from this software
- without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/keycodemapdb/LICENSE.GPL2 b/keycodemapdb/LICENSE.GPL2
deleted file mode 100644
index d511905..0000000
--- a/keycodemapdb/LICENSE.GPL2
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License along
- with this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/keycodemapdb/README b/keycodemapdb/README
deleted file mode 100644
index a3c3c9f..0000000
--- a/keycodemapdb/README
+++ /dev/null
@@ -1,114 +0,0 @@
- Key code / scan code / key symbol mapping database
- ==================================================
-
-This module provides a database that maps between different
-key code / scan code / key symbol sets:
-
- - Linux evdev
- - OS-X
- - AT Set 1
- - AT Set 2
- - AT Set 3
- - XT
- - Linux XT KBD driver
- - USB HID
- - Win32
- - XWin XT
- - XKBD XT
- - Xorg Evdev
- - Xorg KBD
- - Xorg OS-X
- - XOrg Cygwin
- - RFB
-
-Licensing
----------
-
-The contents of this package are dual licensed under the terms of:
-
- - GNU General Public License (version 2 or later)
- - 3-clause BSD License
-
-The output files generated by keymap-gen may be distributed & used under
-the terms of either of the above licenses.
-
-Data formats
-------------
-
-The following output formats are possible
-
- - Code map
-
- An array mapping between key code sets values
-
- Indexes in the array are values from the source code set.
- Entries in the array are values from the target code set
-
-
- - Code table
-
- An array listing all values in a key code set
-
- Indexes in the array are simply a numeric counter
- Entries in the array are values from the key code set
-
- The size of the array matches the total number of entries in
- the keycode database.
-
-
- - Name map
-
- An array mapping between key code sets values and names
-
- Indexes in the array are values from the source code set
- Entries in the array are names from the target code set
-
-
- - Name table
-
- An array listing all names in a key code set
-
- Indexes in the array are simply a numeric counter
- Entries in the array are values from the key code set
-
- The size of the array matches the total number of entries in
- the keycode database.
-
-
-Output languages
-----------------
-
-The tool is capable of generating data tables for the following
-programming languages / environments
-
- - Standard C
- - GLib2 (standard C, but with GLib2 data types)
- - Python
- - Perl
-
-
-Usage
------
-
-Map values from AT Set 1 to USB HID, generating tables for the
-C programming language
-
- $ keymap-gen --lang stdc code-map data/keymaps.csv atset1 usb
-
-Generate a tables of names for Linux key codes, OS-X key codes,
-in python - equivalent array indexes map between the two sets.
-A variable name override is used
-
- $ keymap-gen --varname linux_keycodes --lang stdc \
- code-table data/keymaps.csv linux
- $ keymap-gen --varname osx_keycodes --lang stdc \
- code-table data/keymaps.csv os-x
-
-Generate a mapping from XOrg XWin values to Win32 names
-
- $ keymap-gen --lang perl name-map data/keymaps.csv xorgxwin win32
-
-Generate a table of names for Linux key codes in Perl
-
- $ keymap-gen --lang perl name-table data/keymaps.csv linux
-
diff --git a/keycodemapdb/data/README b/keycodemapdb/data/README
deleted file mode 100644
index 6b56534..0000000
--- a/keycodemapdb/data/README
+++ /dev/null
@@ -1,89 +0,0 @@
-This directory contains the raw data for mapping between different
-keyboard codes. Naming if often based on the US keyboard layout, but
-does not indicate the symbol actually generated by the key.
-
-The columns currently in this data set are:
-
-Linux
------
-
-Name and value of the hardware independent keycodes used by the linux
-kernel and exposed through the input subsystem.
-
-References: linux/input.h
-
-macOS
------
-
-Low level key codes as exposed by Mac OS X/macOS.
-
-References: Carbon/HIToolbox/Events.h
-
-PC scan code sets
------------------
-
-Scan codes for the three orignal PC keyboard generations:
-
- Set 1: XT
- Set 2: AT
- Set 3: PS/2
-
-The sets include codes for modern keys as well and not just the keys
-present on those original keyboards.
-
-References: linux/drivers/input/keyboard/atkbd.c
-
-USB HID
--------
-
-Codes as specified by the HID profile in USB.
-
-References: linux/drivers/hid/usbhid/usbkbd.c
-
-Windows Virtual-key codes
--------------------------
-
-The low level, hardware independent "VKEYs" exposed by Windows.
-
-References: mingw32/winuser.h
-
-XWin XT
--------
-
-X11 keycodes generated by the XWin server. Based on the XT scan code
-set.
-
-References: xorg-server/hw/xwin/{winkeybd.c,winkeynames.h}
-
-Xfree86 KBD XT
---------------
-
-X11 keycodes generated by the Xfree86 keyboard drivers. Based on the XT
-scan code set.
-
-References: xf86-input-keyboard/src/at_scancode.c
-
-X11 keysyms
------------
-
-Corresponding X11 keysym value(s) for a US keyboard layout.
-
-WARNING: These columns represent symbols, not physical keys, and should
- be used with extreme care.
-
-References: http://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h
-
-HTML KeyboardEvent.code
------------------------
-
-Key codes seen in the KeyboardEvent.code attribute as part of the
-UI Events specification.
-
-References: https://www.w3.org/TR/uievents-code/
-
-XKEYBOARD key names
--------------------
-
-Hardware independent key names as used in the XKEYBOARD extension.
-
-References: /usr/share/X11/xkb/keycodes/
diff --git a/keycodemapdb/data/keymaps.csv b/keycodemapdb/data/keymaps.csv
deleted file mode 100644
index 6b1631e..0000000
--- a/keycodemapdb/data/keymaps.csv
+++ /dev/null
@@ -1,539 +0,0 @@
-"Linux Name","Linux Keycode","OS-X Name","OS-X Keycode","AT set1 keycode","AT set2 keycode","AT set3 keycode","USB Keycodes","Win32 Name","Win32 Keycode","Xwin XT","Xfree86 KBD XT","X11 keysym name","X11 keysym","HTML code","XKB key name","QEMU QKeyCode","Sun KBD","Apple ADB"
-KEY_RESERVED,0,,0xff,,,,,,,,,,,,,unmapped,,0xff
-KEY_ESC,1,Escape,0x35,0x01,0x76,0x08,41,VK_ESCAPE,0x1b,1,1,XK_Escape,0xff1b,Escape,ESC,esc,0x1d,0x35
-KEY_1,2,ANSI_1,0x12,0x02,0x16,0x16,30,VK_1,0x31,2,2,XK_1,0x0031,Digit1,AE01,1,0x1e,0x12
-KEY_1,2,ANSI_1,0x12,0x02,0x16,0x16,30,VK_1,0x31,2,2,XK_exclam,0x0021,Digit1,AE01,1,0x1e,0x12
-KEY_2,3,ANSI_2,0x13,0x03,0x1e,0x1e,31,VK_2,0x32,3,3,XK_2,0x0032,Digit2,AE02,2,0x1f,0x13
-KEY_2,3,ANSI_2,0x13,0x03,0x1e,0x1e,31,VK_2,0x32,3,3,XK_at,0x0040,Digit2,AE02,2,0x1f,0x13
-KEY_3,4,ANSI_3,0x14,0x04,0x26,0x26,32,VK_3,0x33,4,4,XK_3,0x0033,Digit3,AE03,3,0x20,0x14
-KEY_3,4,ANSI_3,0x14,0x04,0x26,0x26,32,VK_3,0x33,4,4,XK_numbersign,0x0023,Digit3,AE03,3,0x20,0x14
-KEY_4,5,ANSI_4,0x15,0x05,0x25,0x25,33,VK_4,0x34,5,5,XK_4,0x0034,Digit4,AE04,4,0x21,0x15
-KEY_4,5,ANSI_4,0x15,0x05,0x25,0x25,33,VK_4,0x34,5,5,XK_dollar,0x0024,Digit4,AE04,4,0x21,0x15
-KEY_5,6,ANSI_5,0x17,0x06,0x2e,0x2e,34,VK_5,0x35,6,6,XK_5,0x0035,Digit5,AE05,5,0x22,0x17
-KEY_5,6,ANSI_5,0x17,0x06,0x2e,0x2e,34,VK_5,0x35,6,6,XK_percent,0x0025,Digit5,AE05,5,0x22,0x17
-KEY_6,7,ANSI_6,0x16,0x07,0x36,0x36,35,VK_6,0x36,7,7,XK_6,0x0036,Digit6,AE06,6,0x23,0x16
-KEY_6,7,ANSI_6,0x16,0x07,0x36,0x36,35,VK_6,0x36,7,7,XK_asciicircum,0x005e,Digit6,AE06,6,0x23,0x16
-KEY_7,8,ANSI_7,0x1a,0x08,0x3d,0x3d,36,VK_7,0x37,8,8,XK_7,0x0037,Digit7,AE07,7,0x24,0x1a
-KEY_7,8,ANSI_7,0x1a,0x08,0x3d,0x3d,36,VK_7,0x37,8,8,XK_ampersand,0x0026,Digit7,AE07,7,0x24,0x1a
-KEY_8,9,ANSI_8,0x1c,0x09,0x3e,0x3e,37,VK_8,0x38,9,9,XK_8,0x0038,Digit8,AE08,8,0x25,0x1c
-KEY_8,9,ANSI_8,0x1c,0x09,0x3e,0x3e,37,VK_8,0x38,9,9,XK_asterisk,0x002a,Digit8,AE08,8,0x25,0x1c
-KEY_9,10,ANSI_9,0x19,0x0a,0x46,0x46,38,VK_9,0x39,10,10,XK_9,0x0039,Digit9,AE09,9,0x26,0x19
-KEY_9,10,ANSI_9,0x19,0x0a,0x46,0x46,38,VK_9,0x39,10,10,XK_parenleft,0x0028,Digit9,AE09,9,0x26,0x19
-KEY_0,11,ANSI_0,0x1d,0x0b,0x45,0x45,39,VK_0,0x30,11,11,XK_0,0x0030,Digit0,AE10,0,0x27,0x1d
-KEY_0,11,ANSI_0,0x1d,0x0b,0x45,0x45,39,VK_0,0x30,11,11,XK_parenright,0x0029,Digit0,AE10,0,0x27,0x1d
-KEY_MINUS,12,ANSI_Minus,0x1b,0x0c,0x4e,0x4e,45,VK_OEM_MINUS,0xbd,12,12,XK_minus,0x002d,Minus,AE11,minus,0x28,0x1b
-KEY_MINUS,12,ANSI_Minus,0x1b,0x0c,0x4e,0x4e,45,VK_OEM_MINUS,0xbd,12,12,XK_underscore,0x005f,Minus,AE11,minus,0x28,0x1b
-KEY_EQUAL,13,ANSI_Equal,0x18,0x0d,0x55,0x55,46,VK_OEM_PLUS,0xbb,13,13,XK_equal,0x003d,Equal,AE12,equal,0x29,0x18
-KEY_EQUAL,13,ANSI_Equal,0x18,0x0d,0x55,0x55,46,VK_OEM_PLUS,0xbb,13,13,XK_plus,0x002b,Equal,AE12,equal,0x29,0x18
-KEY_BACKSPACE,14,Delete,0x33,0x0e,0x66,0x66,42,VK_BACK,0x08,14,14,XK_BackSpace,0xff08,Backspace,BKSP,backspace,0x2b,0x33
-KEY_TAB,15,Tab,0x30,0x0f,0x0d,0x0d,43,VK_TAB,0x09,15,15,XK_Tab,0xff09,Tab,TAB,tab,0x35,0x30
-KEY_Q,16,ANSI_Q,0xc,0x10,0x15,0x15,20,VK_Q,0x51,16,16,XK_Q,0x0051,KeyQ,AD01,q,0x36,0xc
-KEY_Q,16,ANSI_Q,0xc,0x10,0x15,0x15,20,VK_Q,0x51,16,16,XK_q,0x0071,KeyQ,AD01,q,0x36,0xc
-KEY_W,17,ANSI_W,0xd,0x11,0x1d,0x1d,26,VK_W,0x57,17,17,XK_W,0x0057,KeyW,AD02,w,0x37,0xd
-KEY_W,17,ANSI_W,0xd,0x11,0x1d,0x1d,26,VK_W,0x57,17,17,XK_w,0x0077,KeyW,AD02,w,0x37,0xd
-KEY_E,18,ANSI_E,0xe,0x12,0x24,0x24,8,VK_E,0x45,18,18,XK_E,0x0045,KeyE,AD03,e,0x38,0xe
-KEY_E,18,ANSI_E,0xe,0x12,0x24,0x24,8,VK_E,0x45,18,18,XK_e,0x0065,KeyE,AD03,e,0x38,0xe
-KEY_R,19,ANSI_R,0xf,0x13,0x2d,0x2d,21,VK_R,0x52,19,19,XK_R,0x0052,KeyR,AD04,r,0x39,0xf
-KEY_R,19,ANSI_R,0xf,0x13,0x2d,0x2d,21,VK_R,0x52,19,19,XK_r,0x0072,KeyR,AD04,r,0x39,0xf
-KEY_T,20,ANSI_T,0x11,0x14,0x2c,0x2c,23,VK_T,0x54,20,20,XK_T,0x0054,KeyT,AD05,t,0x3a,0x11
-KEY_T,20,ANSI_T,0x11,0x14,0x2c,0x2c,23,VK_T,0x54,20,20,XK_t,0x0074,KeyT,AD05,t,0x3a,0x11
-KEY_Y,21,ANSI_Y,0x10,0x15,0x35,0x35,28,VK_Y,0x59,21,21,XK_Y,0x0059,KeyY,AD06,y,0x3b,0x10
-KEY_Y,21,ANSI_Y,0x10,0x15,0x35,0x35,28,VK_Y,0x59,21,21,XK_y,0x0079,KeyY,AD06,y,0x3b,0x10
-KEY_U,22,ANSI_U,0x20,0x16,0x3c,0x3c,24,VK_U,0x55,22,22,XK_U,0x0055,KeyU,AD07,u,0x3c,0x20
-KEY_U,22,ANSI_U,0x20,0x16,0x3c,0x3c,24,VK_U,0x55,22,22,XK_u,0x0075,KeyU,AD07,u,0x3c,0x20
-KEY_I,23,ANSI_I,0x22,0x17,0x43,0x43,12,VK_I,0x49,23,23,XK_I,0x0049,KeyI,AD08,i,0x3d,0x22
-KEY_I,23,ANSI_I,0x22,0x17,0x43,0x43,12,VK_I,0x49,23,23,XK_i,0x0069,KeyI,AD08,i,0x3d,0x22
-KEY_O,24,ANSI_O,0x1f,0x18,0x44,0x44,18,VK_O,0x4f,24,24,XK_O,0x004f,KeyO,AD09,o,0x3e,0x1f
-KEY_O,24,ANSI_O,0x1f,0x18,0x44,0x44,18,VK_O,0x4f,24,24,XK_o,0x006f,KeyO,AD09,o,0x3e,0x1f
-KEY_P,25,ANSI_P,0x23,0x19,0x4d,0x4d,19,VK_P,0x50,25,25,XK_P,0x0050,KeyP,AD10,p,0x3f,0x23
-KEY_P,25,ANSI_P,0x23,0x19,0x4d,0x4d,19,VK_P,0x50,25,25,XK_p,0x0070,KeyP,AD10,p,0x3f,0x23
-KEY_LEFTBRACE,26,ANSI_LeftBracket,0x21,0x1a,0x54,0x54,47,VK_OEM_4,0xdb,26,26,XK_bracketleft,0x005b,BracketLeft,AD11,bracket_left,0x40,0x21
-KEY_LEFTBRACE,26,ANSI_LeftBracket,0x21,0x1a,0x54,0x54,47,VK_OEM_4,0xdb,26,26,XK_braceleft,0x007b,BracketLeft,AD11,bracket_left,0x40,0x21
-KEY_RIGHTBRACE,27,ANSI_RightBracket,0x1e,0x1b,0x5b,0x5b,48,VK_OEM_6,0xdd,27,27,XK_bracketright,0x005d,BracketRight,AD12,bracket_right,0x41,0x1e
-KEY_RIGHTBRACE,27,ANSI_RightBracket,0x1e,0x1b,0x5b,0x5b,48,VK_OEM_6,0xdd,27,27,XK_braceright,0x007d,BracketRight,AD12,bracket_right,0x41,0x1e
-KEY_ENTER,28,Return,0x24,0x1c,0x5a,0x5a,40,VK_RETURN,0x0d,28,28,XK_Return,0xff0d,Enter,RTRN,ret,0x59,0x24
-KEY_LEFTCTRL,29,Control,0x3b,0x1d,0x14,0x11,224,VK_LCONTROL,0xa2,29,29,XK_Control_L,0xffe3,ControlLeft,LCTL,ctrl,0x4c,0x36
-KEY_LEFTCTRL,29,Control,0x3b,0x1d,0x14,0x11,224,VK_CONTROL,0x11,29,29,XK_Control_L,0xffe3,ControlLeft,LCTL,ctrl,0x4c,0x36
-KEY_A,30,ANSI_A,0x0,0x1e,0x1c,0x1c,4,VK_A,0x41,30,30,XK_A,0x0041,KeyA,AC01,a,0x4d,0x0
-KEY_A,30,ANSI_A,0x0,0x1e,0x1c,0x1c,4,VK_A,0x41,30,30,XK_a,0x0061,KeyA,AC01,a,0x4d,0x0
-KEY_S,31,ANSI_S,0x1,0x1f,0x1b,0x1b,22,VK_S,0x53,31,31,XK_S,0x0053,KeyS,AC02,s,0x4e,0x1
-KEY_S,31,ANSI_S,0x1,0x1f,0x1b,0x1b,22,VK_S,0x53,31,31,XK_s,0x0073,KeyS,AC02,s,0x4e,0x1
-KEY_D,32,ANSI_D,0x2,0x20,0x23,0x23,7,VK_D,0x44,32,32,XK_D,0x0044,KeyD,AC03,d,0x4f,0x2
-KEY_D,32,ANSI_D,0x2,0x20,0x23,0x23,7,VK_D,0x44,32,32,XK_d,0x0064,KeyD,AC03,d,0x4f,0x2
-KEY_F,33,ANSI_F,0x3,0x21,0x2b,0x2b,9,VK_F,0x46,33,33,XK_F,0x0046,KeyF,AC04,f,0x50,0x3
-KEY_F,33,ANSI_F,0x3,0x21,0x2b,0x2b,9,VK_F,0x46,33,33,XK_f,0x0066,KeyF,AC04,f,0x50,0x3
-KEY_G,34,ANSI_G,0x5,0x22,0x34,0x34,10,VK_G,0x47,34,34,XK_G,0x0047,KeyG,AC05,g,0x51,0x5
-KEY_G,34,ANSI_G,0x5,0x22,0x34,0x34,10,VK_G,0x47,34,34,XK_g,0x0067,KeyG,AC05,g,0x51,0x5
-KEY_H,35,ANSI_H,0x4,0x23,0x33,0x33,11,VK_H,0x48,35,35,XK_H,0x0048,KeyH,AC06,h,0x52,0x4
-KEY_H,35,ANSI_H,0x4,0x23,0x33,0x33,11,VK_H,0x48,35,35,XK_h,0x0068,KeyH,AC06,h,0x52,0x4
-KEY_J,36,ANSI_J,0x26,0x24,0x3b,0x3b,13,VK_J,0x4a,36,36,XK_J,0x004a,KeyJ,AC07,j,0x53,0x26
-KEY_J,36,ANSI_J,0x26,0x24,0x3b,0x3b,13,VK_J,0x4a,36,36,XK_j,0x006a,KeyJ,AC07,j,0x53,0x26
-KEY_K,37,ANSI_K,0x28,0x25,0x42,0x42,14,VK_K,0x4b,37,37,XK_K,0x004b,KeyK,AC08,k,0x54,0x28
-KEY_K,37,ANSI_K,0x28,0x25,0x42,0x42,14,VK_K,0x4b,37,37,XK_k,0x006b,KeyK,AC08,k,0x54,0x28
-KEY_L,38,ANSI_L,0x25,0x26,0x4b,0x4b,15,VK_L,0x4c,38,38,XK_L,0x004c,KeyL,AC09,l,0x55,0x25
-KEY_L,38,ANSI_L,0x25,0x26,0x4b,0x4b,15,VK_L,0x4c,38,38,XK_l,0x006c,KeyL,AC09,l,0x55,0x25
-KEY_SEMICOLON,39,ANSI_Semicolon,0x29,0x27,0x4c,0x4c,51,VK_OEM_1,0xba,39,39,XK_semicolon,0x003b,Semicolon,AC10,semicolon,0x56,0x29
-KEY_SEMICOLON,39,ANSI_Semicolon,0x29,0x27,0x4c,0x4c,51,VK_OEM_1,0xba,39,39,XK_colon,0x003a,Semicolon,AC10,semicolon,0x56,0x29
-KEY_APOSTROPHE,40,ANSI_Quote,0x27,0x28,0x52,0x52,52,VK_OEM_7,0xde,40,40,XK_apostrophe,0x0027,Quote,AC11,apostrophe,0x57,0x27
-KEY_APOSTROPHE,40,ANSI_Quote,0x27,0x28,0x52,0x52,52,VK_OEM_7,0xde,40,40,XK_quotedbl,0x0022,Quote,AC11,apostrophe,0x57,0x27
-KEY_GRAVE,41,ANSI_Grave,0x32,0x29,0x0e,0x0e,53,VK_OEM_3,0xc0,41,41,XK_grave,0x0060,Backquote,TLDE,grave_accent,0x2a,0x32
-KEY_GRAVE,41,ANSI_Grave,0x32,0x29,0x0e,0x0e,53,VK_OEM_3,0xc0,41,41,XK_grave,0x0060,Backquote,AB00,grave_accent,0x2a,0x32
-KEY_GRAVE,41,ANSI_Grave,0x32,0x29,0x0e,0x0e,53,VK_OEM_3,0xc0,41,41,XK_asciitilde,0x007e,Backquote,TLDE,grave_accent,0x2a,0x32
-KEY_GRAVE,41,ANSI_Grave,0x32,0x29,0x0e,0x0e,53,VK_OEM_3,0xc0,41,41,XK_asciitilde,0x007e,Backquote,AB00,grave_accent,0x2a,0x32
-KEY_SHIFT,42,Shift,0x38,0x2a,0x12,0x12,225,VK_SHIFT,0x10,42,42,XK_Shift_L,0xffe1,ShiftLeft,LFSH,shift,0x63,0x38
-KEY_LEFTSHIFT,42,Shift,0x38,0x2a,0x12,0x12,225,VK_LSHIFT,0xa0,42,42,XK_Shift_L,0xffe1,ShiftLeft,LFSH,shift,0x63,0x38
-KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,49,VK_OEM_5,0xdc,43,43,XK_backslash,0x005c,Backslash,BKSL,backslash,0x58,0x2a
-KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,49,VK_OEM_5,0xdc,43,43,XK_backslash,0x005c,Backslash,AC12,backslash,0x58,0x2a
-KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,49,VK_OEM_5,0xdc,43,43,XK_bar,0x007c,Backslash,BKSL,backslash,0x58,0x2a
-KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,49,VK_OEM_5,0xdc,43,43,XK_bar,0x007c,Backslash,AC12,backslash,0x58,0x2a
-KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,50,VK_OEM_5,0xdc,43,43,XK_backslash,0x005c,Backslash,BKSL,backslash,0x58,0x2a
-KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,50,VK_OEM_5,0xdc,43,43,XK_backslash,0x005c,Backslash,AC12,backslash,0x58,0x2a
-KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,50,VK_OEM_5,0xdc,43,43,XK_bar,0x007c,Backslash,BKSL,backslash,0x58,0x2a
-KEY_BACKSLASH,43,ANSI_Backslash,0x2a,0x2b,0x5d,0x5c,50,VK_OEM_5,0xdc,43,43,XK_bar,0x007c,Backslash,AC12,backslash,0x58,0x2a
-KEY_Z,44,ANSI_Z,0x6,0x2c,0x1a,0x1a,29,VK_Z,0x5a,44,44,XK_Z,0x005a,KeyZ,AB01,z,0x64,0x6
-KEY_Z,44,ANSI_Z,0x6,0x2c,0x1a,0x1a,29,VK_Z,0x5a,44,44,XK_z,0x007a,KeyZ,AB01,z,0x64,0x6
-KEY_X,45,ANSI_X,0x7,0x2d,0x22,0x22,27,VK_X,0x58,45,45,XK_X,0x0058,KeyX,AB02,x,0x65,0x7
-KEY_X,45,ANSI_X,0x7,0x2d,0x22,0x22,27,VK_X,0x58,45,45,XK_x,0x0078,KeyX,AB02,x,0x65,0x7
-KEY_C,46,ANSI_C,0x8,0x2e,0x21,0x21,6,VK_C,0x43,46,46,XK_C,0x0043,KeyC,AB03,c,0x66,0x8
-KEY_C,46,ANSI_C,0x8,0x2e,0x21,0x21,6,VK_C,0x43,46,46,XK_c,0x0063,KeyC,AB03,c,0x66,0x8
-KEY_V,47,ANSI_V,0x9,0x2f,0x2a,0x2a,25,VK_V,0x56,47,47,XK_V,0x0056,KeyV,AB04,v,0x67,0x9
-KEY_V,47,ANSI_V,0x9,0x2f,0x2a,0x2a,25,VK_V,0x56,47,47,XK_v,0x0076,KeyV,AB04,v,0x67,0x9
-KEY_B,48,ANSI_B,0xb,0x30,0x32,0x32,5,VK_B,0x42,48,48,XK_B,0x0042,KeyB,AB05,b,0x68,0xb
-KEY_B,48,ANSI_B,0xb,0x30,0x32,0x32,5,VK_B,0x42,48,48,XK_b,0x0062,KeyB,AB05,b,0x68,0xb
-KEY_N,49,ANSI_N,0x2d,0x31,0x31,0x31,17,VK_N,0x4e,49,49,XK_N,0x004e,KeyN,AB06,n,0x69,0x2d
-KEY_N,49,ANSI_N,0x2d,0x31,0x31,0x31,17,VK_N,0x4e,49,49,XK_n,0x006e,KeyN,AB06,n,0x69,0x2d
-KEY_M,50,ANSI_M,0x2e,0x32,0x3a,0x3a,16,VK_M,0x4d,50,50,XK_M,0x004d,KeyM,AB07,m,0x6a,0x2e
-KEY_M,50,ANSI_M,0x2e,0x32,0x3a,0x3a,16,VK_M,0x4d,50,50,XK_m,0x006d,KeyM,AB07,m,0x6a,0x2e
-KEY_COMMA,51,ANSI_Comma,0x2b,0x33,0x41,0x41,54,VK_OEM_COMMA,0xbc,51,51,XK_comma,0x002c,Comma,AB08,comma,0x6b,0x2b
-KEY_COMMA,51,ANSI_Comma,0x2b,0x33,0x41,0x41,54,VK_OEM_COMMA,0xbc,51,51,XK_less,0x003c,Comma,AB08,comma,0x6b,0x2b
-KEY_DOT,52,ANSI_Period,0x2f,0x34,0x49,0x49,55,VK_OEM_PERIOD,0xbe,52,52,XK_period,0x002e,Period,AB09,dot,0x6c,0x2f
-KEY_DOT,52,ANSI_Period,0x2f,0x34,0x49,0x49,55,VK_OEM_PERIOD,0xbe,52,52,XK_greater,0x003e,Period,AB09,dot,0x6c,0x2f
-KEY_SLASH,53,ANSI_Slash,0x2c,0x35,0x4a,0x4a,56,VK_OEM_2,0xbf,53,53,XK_slash,0x002f,Slash,AB10,slash,0x6d,0x2c
-KEY_SLASH,53,ANSI_Slash,0x2c,0x35,0x4a,0x4a,56,VK_OEM_2,0xbf,53,53,XK_question,0x003f,Slash,AB10,slash,0x6d,0x2c
-KEY_RIGHTSHIFT,54,RightShift,0x3c,0x36,0x59,0x59,229,VK_RSHIFT,0xa1,54,54,XK_Shift_R,0xffe2,ShiftRight,RTSH,shift_r,0x6e,0x7b
-KEY_KPASTERISK,55,ANSI_KeypadMultiply,0x43,0x37,0x7c,0x7e,85,VK_MULTIPLY,0x6a,55,55,XK_multiply,0x00d7,NumpadMultiply,KPMU,asterisk,0x2f,0x43
-KEY_KPASTERISK,55,ANSI_KeypadMultiply,0x43,0x37,0x7c,0x7e,85,VK_MULTIPLY,0x6a,55,55,XK_multiply,0x00d7,NumpadMultiply,KPMU,kp_multiply,0x2f,0x43
-KEY_LEFTALT,56,Option,0x3a,0x38,0x11,0x19,226,VK_LMENU,0xa4,56,56,XK_Alt_L,0xffe9,AltLeft,LALT,alt,0x13,0x3a
-KEY_LEFTALT,56,Option,0x3a,0x38,0x11,0x19,226,VK_MENU,0x12,56,56,XK_Alt_L,0xffe9,AltLeft,LALT,alt,0x13,0x3a
-KEY_SPACE,57,Space,0x31,0x39,0x29,0x29,44,VK_SPACE,0x20,57,57,XK_space,0x0020,Space,SPCE,spc,0x79,0x31
-KEY_CAPSLOCK,58,CapsLock,0x39,0x3a,0x58,0x14,57,VK_CAPITAL,0x14,58,58,XK_Caps_Lock,0xffe5,CapsLock,CAPS,caps_lock,0x77,0x39
-KEY_F1,59,F1,0x7a,0x3b,0x05,0x07,58,VK_F1,0x70,59,59,XK_F1,0xffbe,F1,FK01,f1,0x05,0x7a
-KEY_F2,60,F2,0x78,0x3c,0x06,0x0f,59,VK_F2,0x71,60,60,XK_F2,0xffbf,F2,FK02,f2,0x06,0x78
-KEY_F3,61,F3,0x63,0x3d,0x04,0x17,60,VK_F3,0x72,61,61,XK_F3,0xffc0,F3,FK03,f3,0x08,0x63
-KEY_F4,62,F4,0x76,0x3e,0x0c,0x1f,61,VK_F4,0x73,62,62,XK_F4,0xffc1,F4,FK04,f4,0x0a,0x76
-KEY_F5,63,F5,0x60,0x3f,0x03,0x27,62,VK_F5,0x74,63,63,XK_F5,0xffc2,F5,FK05,f5,0x0c,0x60
-KEY_F6,64,F6,0x61,0x40,0x0b,0x2f,63,VK_F6,0x75,64,64,XK_F6,0xffc3,F6,FK06,f6,0x0e,0x61
-KEY_F7,65,F7,0x62,0x41,0x83,0x37,64,VK_F7,0x76,65,65,XK_F7,0xffc4,F7,FK07,f7,0x10,0x62
-KEY_F8,66,F8,0x64,0x42,0x0a,0x3f,65,VK_F8,0x77,66,66,XK_F8,0xffc5,F8,FK08,f8,0x11,0x64
-KEY_F9,67,F9,0x65,0x43,0x01,0x47,66,VK_F9,0x78,67,67,XK_F9,0xffc6,F9,FK09,f9,0x12,0x65
-KEY_F10,68,F10,0x6d,0x44,0x09,0x4f,67,VK_F10,0x79,68,68,XK_F10,0xffc7,F10,FK10,f10,0x07,0x6d
-KEY_NUMLOCK,69,ANSI_KeypadClear,0x47,0x45,0x77,0x76,83,VK_NUMLOCK,0x90,69,69,XK_Num_Lock,0xff7f,NumLock,NMLK,num_lock,0x62,0x47
-KEY_SCROLLLOCK,70,,,0x46,0x7e,0x5f,71,VK_SCROLL,0x91,70,70,XK_Scroll_Lock,0xff14,ScrollLock,SCLK,scroll_lock,0x17,0x6b
-KEY_KP7,71,ANSI_Keypad7,0x59,0x47,0x6c,0x6c,95,VK_NUMPAD7,0x67,71,71,XK_KP_7,0xffb7,Numpad7,KP7,kp_7,0x44,0x59
-KEY_KP8,72,ANSI_Keypad8,0x5b,0x48,0x75,0x75,96,VK_NUMPAD8,0x68,72,72,XK_KP_8,0xffb8,Numpad8,KP8,kp_8,0x45,0x5b
-KEY_KP9,73,ANSI_Keypad9,0x5c,0x49,0x7d,0x7d,97,VK_NUMPAD9,0x69,73,73,XK_KP_9,0xffb9,Numpad9,KP9,kp_9,0x46,0x5c
-KEY_KPMINUS,74,ANSI_KeypadMinus,0x4e,0x4a,0x7b,0x4e,86,VK_SUBTRACT,0x6d,74,74,XK_KP_Subtract,0xffad,NumpadSubtract,KPSU,kp_subtract,0x47,0x4e
-KEY_KP4,75,ANSI_Keypad4,0x56,0x4b,0x6b,0x6b,92,VK_NUMPAD4,0x64,75,75,XK_KP_4,0xffb4,Numpad4,KP4,kp_4,0x5b,0x56
-KEY_KP5,76,ANSI_Keypad5,0x57,0x4c,0x73,0x73,93,VK_NUMPAD5,0x65,76,76,XK_KP_5,0xffb5,Numpad5,KP5,kp_5,0x5c,0x57
-KEY_KP6,77,ANSI_Keypad6,0x58,0x4d,0x74,0x74,94,VK_NUMPAD6,0x66,77,77,XK_KP_6,0xffb6,Numpad6,KP6,kp_6,0x5d,0x58
-KEY_KPPLUS,78,ANSI_KeypadPlus,0x45,0x4e,0x79,0x7c,87,VK_ADD,0x6b,78,78,XK_KP_Add,0xffab,NumpadAdd,KPAD,kp_add,0x7d,0x45
-KEY_KP1,79,ANSI_Keypad1,0x53,0x4f,0x69,0x69,89,VK_NUMPAD1,0x61,79,79,XK_KP_1,0xffb1,Numpad1,KP1,kp_1,0x70,0x53
-KEY_KP2,80,ANSI_Keypad2,0x54,0x50,0x72,0x72,90,VK_NUMPAD2,0x62,80,80,XK_KP_2,0xffb2,Numpad2,KP2,kp_2,0x71,0x54
-KEY_KP3,81,ANSI_Keypad3,0x55,0x51,0x7a,0x7a,91,VK_NUMPAD3,0x63,81,81,XK_KP_3,0xffb3,Numpad3,KP3,kp_3,0x72,0x55
-KEY_KP0,82,ANSI_Keypad0,0x52,0x52,0x70,0x70,98,VK_NUMPAD0,0x60,82,82,XK_KP_0,0xffb0,Numpad0,KP0,kp_0,0x5e,0x52
-KEY_KPDOT,83,ANSI_KeypadDecimal,0x41,0x53,0x71,0x71,99,VK_DECIMAL,0x6e,83,83,XK_KP_Decimal,0xffae,NumpadDecimal,KPDL,kp_decimal,0x32,0x41
-KEY_KPDOT,83,ANSI_KeypadDecimal,0x41,0x53,0x71,0x71,99,VK_DECIMAL,0x6e,83,83,XK_KP_Decimal,0xffae,NumpadDecimal,KPDC,kp_decimal,0x32,0x41
-,84,,,0x54,,,,,,,,,,,,,,
-KEY_ZENKAKUHANKAKU,85,,,0x76,0x5f,,148,,,,,,,Lang5,HZTG,,,
-KEY_102ND,86,,,0x56,0x61,0x13,100,VK_OEM_102,0xe2,86,86,,,IntlBackslash,LSGT,less,0x7c,
-KEY_F11,87,F11,0x67,0x57,0x78,0x56,68,VK_F11,0x7a,87,87,XK_F11,0xffc8,F11,FK11,f11,0x09,0x67
-KEY_F12,88,F12,0x6f,0x58,0x07,0x5e,69,VK_F12,0x7b,88,88,XK_F12,0xffc9,F12,FK12,f12,0x0b,0x6f
-KEY_RO,89,JIS_Underscore,0x5e,0x73,0x51,,135,,,,,,,IntlRo,AB11,ro,,
-KEY_KATAKANA,90,,,0x78,0x63,,146,VK_KANA,0x15,,,,,Katakana,KATA,,,
-KEY_KATAKANA,90,,,0x78,0x63,,146,VK_KANA,0x15,,,,,Lang3,KATA,,,
-KEY_HIRAGANA,91,,,0x77,0x62,0x87,147,,,,,,,Hiragana,HIRA,hiragana,,
-KEY_HIRAGANA,91,,,0x77,0x62,0x87,147,,,,,,,Lang4,HIRA,hiragana,,
-KEY_HENKAN,92,,,0x79,0x64,0x86,138,,,,,,,Convert,HENK,henkan,,
-KEY_KATAKANAHIRAGANA,93,,,0x70,0x13,0x87,136,,,0xc8,0xc8,,,KanaMode,HKTG,katakanahiragana,,
-KEY_MUHENKAN,94,,,0x7b,0x67,0x85,139,,,,,,,NonConvert,NFER,muhenkan,,
-KEY_MUHENKAN,94,,,0x7b,0x67,0x85,139,,,,,,,NonConvert,MUHE,muhenkan,,
-KEY_KPJPCOMMA,95,JIS_KeypadComma,0x5f,0x5c,0x27,,140,,,,,XK_KP_Separator,0xffac,,KPSP,,,
-KEY_KPJPCOMMA,95,JIS_KeypadComma,0x5f,0x5c,0x27,,140,,,,,XK_KP_Separator,0xffac,,JPCM,,,
-KEY_KPENTER,96,ANSI_KeypadEnter,0x4c,0xe01c,0xe05a,0x79,88,,,0x64,0x64,XK_KP_Enter,0xff8d,NumpadEnter,KPEN,kp_enter,0x5a,0x4c
-KEY_RIGHTCTRL,97,RightControl,0x3e,0xe01d,0xe014,0x58,228,VK_RCONTROL,0xa3,0x65,0x65,XK_Control_R,0xffe4,ControlRight,RCTL,ctrl_r,0x4c,0x7d
-KEY_KPSLASH,98,ANSI_KeypadDivide,0x4b,0xe035,0xe04a,0x4a,84,VK_DIVIDE,0x6f,0x68,0x68,XK_KP_Divide,0xffaf,NumpadDivide,KPDV,kp_divide,0x2e,0x4b
-KEY_SYSRQ,99,,,0x54,0x7f,0x57,70,VK_SNAPSHOT,0x2c,0x67,0x67,XK_Sys_Req,0xff15,PrintScreen,PRSC,print,0x16,0x69
-KEY_SYSRQ,99,,,0x54,0x7f,0x57,70,VK_SNAPSHOT,0x2c,0x67,0x67,XK_Sys_Req,0xff15,PrintScreen,SYRQ,sysrq,0x16,0x69
-KEY_RIGHTALT,100,RightOption,0x3d,0xe038,0xe011,0x39,230,VK_RMENU,0xa5,0x69,0x69,XK_Alt_R,0xffea,AltRight,ALGR,alt_r,0x0d,0x7c
-KEY_RIGHTALT,100,RightOption,0x3d,0xe038,0xe011,0x39,230,VK_RMENU,0xa5,0x69,0x69,XK_Alt_R,0xffea,AltRight,RALT,alt_r,0x0d,0x7c
-KEY_LINEFEED,101,,,0x5b,,,,,,,,,,,LNFD,lf,0x6f,
-KEY_HOME,102,Home,0x73,0xe047,0xe06c,0x6e,74,VK_HOME,0x24,0x59,0x59,XK_Home,0xff50,Home,HOME,home,0x34,0x73
-KEY_UP,103,UpArrow,0x7e,0xe048,0xe075,0x63,82,VK_UP,0x26,0x5a,0x5a,XK_Up,0xff52,ArrowUp,UP,up,0x14,0x3e
-KEY_PAGEUP,104,PageUp,0x74,0xe049,0xe07d,0x6f,75,VK_PRIOR,0x21,0x5b,0x5b,XK_Page_Up,0xff55,PageUp,PGUP,pgup,0x60,0x74
-KEY_LEFT,105,LeftArrow,0x7b,0xe04b,0xe06b,0x61,80,VK_LEFT,0x25,0x5c,0x5c,XK_Left,0xff51,ArrowLeft,LEFT,left,0x18,0x3b
-KEY_RIGHT,106,RightArrow,0x7c,0xe04d,0xe074,0x6a,79,VK_RIGHT,0x27,0x5e,0x5e,XK_Right,0xff53,ArrowRight,RGHT,right,0x1c,0x3c
-KEY_END,107,End,0x77,0xe04f,0xe069,0x65,77,VK_END,0x23,0x5f,0x5f,XK_End,0xff57,End,END,end,0x4a,0x77
-KEY_DOWN,108,DownArrow,0x7d,0xe050,0xe072,0x60,81,VK_DOWN,0x28,0x60,0x60,XK_Down,0xff54,ArrowDown,DOWN,down,0x1b,0x3d
-KEY_PAGEDOWN,109,PageDown,0x79,0xe051,0xe07a,0x6d,78,VK_NEXT,0x22,0x61,0x61,XK_Page_Down,0xff56,PageDown,PGDN,pgdn,0x7b,0x79
-KEY_INSERT,110,,,0xe052,0xe070,0x67,73,VK_INSERT,0x2d,0x62,0x62,XK_Insert,0xff63,Insert,INS,insert,0x2c,0x72
-KEY_DELETE,111,ForwardDelete,0x75,0xe053,0xe071,0x64,76,VK_DELETE,0x2e,0x63,0x63,XK_Delete,0xffff,Delete,DEL,delete,0x42,0x75
-KEY_DELETE,111,ForwardDelete,0x75,0xe053,0xe071,0x64,76,VK_DELETE,0x2e,0x63,0x63,XK_Delete,0xffff,Delete,DELE,,0x42,0x75
-KEY_MACRO,112,,,0xe06f,0xe06f,0x8e,,,,,,,,,I120,,,
-KEY_MUTE,113,Mute,0x4a,0xe020,0xe023,0x9c,127,VK_VOLUME_MUTE,0xad,,,,,AudioVolumeMute,MUTE,audiomute,,
-KEY_MUTE,113,Mute,0x4a,0xe020,0xe023,0x9c,239,VK_VOLUME_MUTE,0xad,,,,,AudioVolumeMute,MUTE,audiomute,,
-KEY_VOLUMEDOWN,114,VolumeDown,0x49,0xe02e,0xe021,0x9d,129,VK_VOLUME_DOWN,0xae,,,,,AudioVolumeDown,VOL-,volumedown,,
-KEY_VOLUMEDOWN,114,VolumeDown,0x49,0xe02e,0xe021,0x9d,238,VK_VOLUME_DOWN,0xae,,,,,AudioVolumeDown,VOL-,volumedown,,
-KEY_VOLUMEUP,115,VolumeUp,0x48,0xe030,0xe032,0x95,128,VK_VOLUME_UP,0xaf,,,,,AudioVolumeUp,VOL+,volumeup,,
-KEY_VOLUMEUP,115,VolumeUp,0x48,0xe030,0xe032,0x95,237,VK_VOLUME_UP,0xaf,,,,,AudioVolumeUp,VOL+,volumeup,,
-KEY_POWER,116,,,0xe05e,0xe037,,102,,,,,,,Power,POWR,power,,0x7f7f
-KEY_KPEQUAL,117,ANSI_KeypadEquals,0x51,0x59,0x0f,,103,,,0x76,0x76,XK_KP_Equal,0xffbd,NumpadEqual,KPEQ,kp_equals,0x2d,0x51
-KEY_KPPLUSMINUS,118,,,0xe04e,0xe079,,,,,,,,,,I126,,,
-KEY_PAUSE,119,,,0xe046,0xe077,0x62,72,VK_PAUSE,0x013,0x66,0x66,XK_Pause,0xff13,Pause,PAUS,pause,0x15,0x71
-KEY_SCALE,120,,,0xe00b,,,,,,,,,,,I128,,,
-KEY_KPCOMMA,121,,,0x7e,0x6d,,133,VK_SEPARATOR??,0x6c,,,,,NumpadComma,KPCO,kp_comma,,
-KEY_KPCOMMA,121,,,0x7e,0x6d,,133,VK_SEPARATOR??,0x6c,,,,,NumpadComma,I129,,,
-KEY_HANGEUL,122,JIS_Kana,0x68,0x72,,,144,VK_HANGEUL,0x15,,0x71,,,Lang1,HNGL,,,
-KEY_HANJA,123,JIS_Eisu,0x66,0x71,,,145,VK_HANJA,0x19,,0x72,,,Lang2,HJCV,,,
-KEY_YEN,124,JIS_Yen,0x5d,0x7d,0x6a,0x5d,137,,,0x7d,0x7d,,,IntlYen,AE13,yen,,
-KEY_LEFTMETA,125,Command,0x37,0xe05b,0xe01f,0x8b,227,VK_LWIN,0x5b,0x6b,0x6b,XK_Meta_L,0xffe7,MetaLeft,LMTA,meta_l,0x78,0x37
-KEY_LEFTMETA,125,Command,0x37,0xe05b,0xe01f,0x8b,227,VK_LWIN,0x5b,0x6b,0x6b,XK_Meta_L,0xffe7,MetaLeft,LWIN,meta_l,0x78,0x37
-KEY_RIGHTMETA,126,RightCommand,0x36,0xe05c,0xe027,0x8c,231,VK_RWIN,0x5c,0x6c,0x6c,XK_Meta_R,0xffe8,MetaRight,RMTA,meta_r,0x7a,0x37
-KEY_RIGHTMETA,126,RightCommand,0x36,0xe05c,0xe027,0x8c,231,VK_RWIN,0x5c,0x6c,0x6c,XK_Meta_R,0xffe8,MetaRight,RWIN,meta_r,0x7a,0x37
-KEY_COMPOSE,127,,0x6e,0xe05d,0xe02f,0x8d,101,VK_APPS,0x5d,0x6d,0x6d,,,ContextMenu,MENU,compose,0x43,
-KEY_COMPOSE,127,,0x6e,0xe05d,0xe02f,0x8d,101,VK_APPS,0x5d,0x6d,0x6d,,,ContextMenu,COMP,compose,0x43,
-KEY_STOP,128,,,0xe068,0xe028,0x0a,120,VK_BROWSER_STOP,0xa9,,,,,BrowserStop,STOP,stop,0x01,
-KEY_STOP,128,,,0xe068,0xe028,0x0a,243,VK_BROWSER_STOP,0xa9,,,,,BrowserStop,STOP,stop,0x01,
-KEY_AGAIN,129,,,0xe005,,0x0b,121,,,,,,,Again,AGAI,again,0x03,
-KEY_PROPS,130,,,0xe006,,0x0c,,,,,,,,Props,PROP,props,0x19,
-KEY_UNDO,131,,,0xe007,,0x10,122,,,,,,,Undo,UNDO,undo,0x1a,
-KEY_FRONT,132,,,0xe00c,,,119,,,,,,,,FRNT,front,0x31,
-KEY_COPY,133,,,0xe078,,0x18,124,,,,,,,Copy,COPY,copy,0x33,
-KEY_OPEN,134,,,0x64,,0x20,116,,,,,,,Open,OPEN,open,0x48,
-KEY_PASTE,135,,,0x65,,0x28,125,,,,,,,Paste,PAST,paste,0x49,
-KEY_FIND,136,,,0xe041,,0x30,126,,,,,,,Find,FIND,find,0x5f,
-KEY_FIND,136,,,0xe041,,0x30,244,,,,,,,Find,FIND,find,0x5f,
-KEY_CUT,137,,,0xe03c,,0x38,123,,,,,,,Cut,CUT,cut,0x61,
-KEY_HELP,138,Help,0x72,0xe075,,0x09,117,VK_HELP,0x2f,,,XK_Help,0xff6a,Help,HELP,help,0x76,
-KEY_MENU,139,,,0xe01e,,0x91,118,,,,,,,,I147,menu,,
-KEY_CALC,140,,,0xe021,0xe02b,0xa3,251,,,,,,,LaunchApp2,I148,calculator,,
-KEY_SETUP,141,,,0x66,,,,,,,,,,,I149,,,
-KEY_SLEEP,142,,,0xe05f,0xe03f,,248,VK_SLEEP,0x5f,,,,,Sleep,I150,sleep,,
-KEY_WAKEUP,143,,,0xe063,0xe05e,,,,,,,,,WakeUp,I151,wake,,
-KEY_FILE,144,,,0x67,,,,,,,,,,,I152,,,
-KEY_SENDFILE,145,,,0x68,,,,,,,,,,,I153,,,
-KEY_DELETEFILE,146,,,0x69,,,,,,,,,,,I154,,,
-KEY_XFER,147,,,0xe013,,0xa2,,,,,,,,,XFER,,,
-KEY_XFER,147,,,0xe013,,0xa2,,,,,,,,,I155,,,
-KEY_PROG1,148,,,0xe01f,,0xa0,,,,,,,,,I156,,,
-KEY_PROG2,149,,,0xe017,,0xa1,,,,,,,,,I157,,,
-KEY_WWW,150,,,0xe002,,,240,,,,,,,,I158,,,
-KEY_MSDOS,151,,,0x6a,,,,,,,,,,,I159,,,
-KEY_SCREENLOCK,152,,,0xe012,,0x96,249,,,,,,,,I160,,,
-KEY_DIRECTION,153,,,0x6b,,,,,,,,,,,I161,,,
-KEY_CYCLEWINDOWS,154,,,0xe026,,0x9b,,,,,,,,,I162,,,
-KEY_MAIL,155,,,0xe06c,0xe048,,,,,,,,,LaunchMail,I163,mail,,
-KEY_BOOKMARKS,156,,,0xe066,0xe018,,,,,,,,,BrowserFavorites,I164,ac_bookmarks,,
-KEY_COMPUTER,157,,,0xe06b,0xe040,,,,,,,,,LaunchApp1,I165,computer,,
-KEY_BACK,158,,,0xe06a,0xe038,,241,VK_BROWSER_BACK,0xa6,,,,,BrowserBack,I166,ac_back,,
-KEY_FORWARD,159,,,0xe069,0xe030,,242,VK_BROWSER_FORWARD,0xa7,,,,,BrowserForward,I167,ac_forward,,
-KEY_CLOSECD,160,,,0xe023,,0x9a,,,,,,,,,I168,,,
-KEY_EJECTCD,161,,,0x6c,,,236,,,,,,,,I169,,,
-KEY_EJECTCLOSECD,162,,,0xe07d,,,,,,,,,,Eject,I170,,,
-KEY_NEXTSONG,163,,,0xe019,0xe04d,0x93,235,VK_MEDIA_NEXT_TRACK,0xb0,,,,,MediaTrackNext,I171,audionext,,
-KEY_PLAYPAUSE,164,,,0xe022,0xe034,,232,VK_MEDIA_PLAY_PAUSE,0xb3,,,,,MediaPlayPause,I172,audioplay,,
-KEY_PREVIOUSSONG,165,,,0xe010,0xe015,0x94,234,VK_MEDIA_PREV_TRACK,0xb1,,,,,MediaTrackPrevious,I173,audioprev,,
-KEY_STOPCD,166,,,0xe024,0xe03b,0x98,233,VK_MEDIA_STOP,0xb2,,,,,MediaStop,I174,audiostop,,
-KEY_RECORD,167,,,0xe031,,0x9e,,,,,,,,,I175,,,
-KEY_REWIND,168,,,0xe018,,0x9f,,,,,,,,,I176,,,
-KEY_PHONE,169,,,0x63,,,,,,,,,,,I177,,,
-KEY_ISO,170,ISO_Section,0xa,,,,,,,,,,,,I178,,,
-KEY_CONFIG,171,,,0xe001,,,,,,,,,,,I179,,,
-KEY_HOMEPAGE,172,,,0xe032,0xe03a,0x97,,VK_BROWSER_HOME,0xac,,,,,BrowserHome,I180,ac_home,,
-KEY_REFRESH,173,,,0xe067,0xe020,,250,VK_BROWSER_REFRESH,0xa8,,,,,BrowserRefresh,I181,ac_refresh,,
-KEY_EXIT,174,,,,,,,,,,,,,,I182,,,
-KEY_MOVE,175,,,,,,,,,,,,,,I183,,,
-KEY_EDIT,176,,,0xe008,,,247,,,,,,,,I184,,,
-KEY_SCROLLUP,177,,,0x75,,,245,,,,,,,,I185,,,
-KEY_SCROLLDOWN,178,,,0xe00f,,,246,,,,,,,,I186,,,
-KEY_KPLEFTPAREN,179,,,0xe076,,,182,,,,,,,NumpadParenLeft,I187,,,
-KEY_KPRIGHTPAREN,180,,,0xe07b,,,183,,,,,,,NumpadParenRight,I188,,,
-KEY_NEW,181,,,0xe009,,,,,,,,,,,I189,,,
-KEY_REDO,182,,,0xe00a,,,,,,,,,,,I190,,,
-KEY_F13,183,F13,0x69,0x5d,0x2f,0x7f,104,VK_F13,0x7c,0x6e,0x6e,,,F13,FK13,,,0x69
-KEY_F14,184,F14,0x6b,0x5e,0x37,0x80,105,VK_F14,0x7d,0x6f,0x6f,,,F14,FK14,,,0x6b
-KEY_F15,185,F15,0x71,0x5f,0x3f,0x81,106,VK_F15,0x7e,0x70,0x70,,,F15,FK15,,,0x71
-KEY_F16,186,F16,0x6a,0x55,,0x82,107,VK_F16,0x7f,0x71,0x71,,,F16,FK16,,,
-KEY_F17,187,F17,0x40,0xe003,,0x83,108,VK_F17,0x80,0x72,0x72,,,F17,FK17,,,
-KEY_F18,188,F18,0x4f,0xe077,,,109,VK_F18,0x81,,,,,F18,FK18,,,
-KEY_F19,189,F19,0x50,0xe004,,,110,VK_F19,0x82,,,,,F19,FK19,,,
-KEY_F20,190,F20,0x5a,0x5a,,,111,VK_F20,0x83,,,,,F20,FK20,,,
-KEY_F21,191,,,0x74,,,112,VK_F21,0x84,,,,,F21,FK21,,,
-KEY_F22,192,,,0xe079,,,113,VK_F22,0x85,,,,,F22,FK22,,,
-KEY_F23,193,,,0x6d,,,114,VK_F23,0x86,,,,,F23,FK23,,,
-KEY_F24,194,,,0x6f,,,115,VK_F24,0x87,,,,,F24,FK24,,,
-,195,,,0xe015,,,,,,,,,,,,,,
-,196,,,0xe016,,,,,,,,,,,,,,
-,197,,,0xe01a,,,,,,,,,,,,,,
-,198,,,0xe01b,,,,,,,,,,,,,,
-,199,,,0xe027,,,,,,,,,,,,,,
-KEY_PLAYCD,200,,,0xe028,,,,,,,,,,,I208,,,
-KEY_PAUSECD,201,,,0xe029,,,,,,,,,,,I209,,,
-KEY_PROG3,202,,,0xe02b,,,,,,,,,,,I210,,,
-KEY_PROG4,203,,,0xe02c,,,,,,,,,,,I211,,,
-KEY_DASHBOARD,204,,,0xe02d,,,,,,,,,,,I212,,,
-KEY_SUSPEND,205,,,0xe025,,,,,,,,,,Suspend,I213,,,
-KEY_CLOSE,206,,,0xe02f,,,,,,,,,,,I214,,,
-KEY_PLAY,207,,,0xe033,,,,VK_PLAY,0xfa,,,,,,I215,,,
-KEY_FASTFORWARD,208,,,0xe034,,,,,,,,,,,I216,,,
-KEY_BASSBOOST,209,,,0xe036,,,,,,,,,,,I217,,,
-KEY_PRINT,210,,,0xe039,,,,VK_PRINT,0x2a,,,,,,I218,,,
-KEY_HP,211,,,0xe03a,,,,,,,,,,,I219,,,
-KEY_CAMERA,212,,,0xe03b,,,,,,,,,,,I220,,,
-KEY_SOUND,213,,,0xe03d,,,,,,,,,,,I221,,,
-KEY_QUESTION,214,,,0xe03e,,,,,,,,,,,I222,,,
-KEY_EMAIL,215,,,0xe03f,,,,VK_LAUNCH_MAIL,0xb4,,,,,,I223,,,
-KEY_CHAT,216,,,0xe040,,,,,,,,,,,I224,,,
-KEY_SEARCH,217,,,0xe065,0xe010,,,VK_BROWSER_SEARCH,0xaa,,,,,BrowserSearch,I225,,,
-KEY_CONNECT,218,,,0xe042,,,,,,,,,,,I226,,,
-KEY_FINANCE,219,,,0xe043,,,,,,,,,,,I227,,,
-KEY_SPORT,220,,,0xe044,,,,,,,,,,,I228,,,
-KEY_SHOP,221,,,0xe045,,,,,,,,,,,I229,,,
-KEY_ALTERASE,222,,,0xe014,,,,,,,,,,,I230,,,
-KEY_CANCEL,223,,,0xe04a,,,,,,,,,,,I231,,,
-KEY_BRIGHTNESSDOWN,224,,,0xe04c,,,,,,,,,,,I232,,,
-KEY_BRIGHTNESSUP,225,,,0xe054,,,,,,,,,,,I233,,,
-KEY_MEDIA,226,,,0xe06d,0xe050,,,,,,,,,MediaSelect,I234,mediaselect,,
-KEY_SWITCHVIDEOMODE,227,,,0xe056,,,,,,,,,,,I235,,,
-KEY_KBDILLUMTOGGLE,228,,,0xe057,,,,,,,,,,,I236,,,
-KEY_KBDILLUMDOWN,229,,,0xe058,,,,,,,,,,,I237,,,
-KEY_KBDILLUMUP,230,,,0xe059,,,,,,,,,,,I238,,,
-KEY_SEND,231,,,0xe05a,,,,,,,,,,,I239,,,
-KEY_REPLY,232,,,0xe064,,,,,,,,,,,I240,,,
-KEY_FORWARDMAIL,233,,,0xe00e,,,,,,,,,,,I241,,,
-KEY_SAVE,234,,,0xe055,,,,,,,,,,,I242,,,
-KEY_DOCUMENTS,235,,,0xe070,,,,,,,,,,,I243,,,
-KEY_BATTERY,236,,,0xe071,,,,,,,,,,,I244,,,
-KEY_BLUETOOTH,237,,,0xe072,,,,,,,,,,,I245,,,
-KEY_WLAN,238,,,0xe073,,,,,,,,,,,I246,,,
-KEY_UWB,239,,,0xe074,,,,,,,,,,,I247,,,
-KEY_UNKNOWN,240,,,,,,,,,,,,,,I248,,,
-KEY_VIDEO_NEXT,241,,,,,,,,,,,,,,I249,,,
-KEY_VIDEO_PREV,242,,,,,,,,,,,,,,I250,,,
-KEY_BRIGHTNESS_CYCLE,243,,,,,,,,,,,,,,I251,,,
-KEY_BRIGHTNESS_ZERO,244,,,,,,,,,,,,,,I252,,,
-KEY_DISPLAY_OFF,245,,,,,,,,,,,,,,I253,,,
-KEY_WIMAX,246,,,,,,,,,,,,,,,,,
-,247,,,,,,,,,,,,,,,,,
-,248,,,,,,,,,,,,,,,,,
-,249,,,,,,,,,,,,,,,,,
-,250,,,,,,,,,,,,,,,,,
-,251,,,,,,,,,,,,,,,,,
-,252,,,,,,,,,,,,,,,,,
-,253,,,,,,,,,,,,,,,,,
-,254,,,,,,,,,,,,,,,,,
-,255,,,,0xe012,,,,,,,,,,,,,
-BTN_MISC,0x100,,,,,,,,,,,,,,,,,
-BTN_0,0x100,,,,,,,VK_LBUTTON,0x01,,,,,,,,,
-BTN_1,0x101,,,,,,,VK_RBUTTON,0x02,,,,,,,,,
-BTN_2,0x102,,,,,,,VK_MBUTTON,0x04,,,,,,,,,
-BTN_3,0x103,,,,,,,VK_XBUTTON1,0x05,,,,,,,,,
-BTN_4,0x104,,,,,,,VK_XBUTTON2,0x06,,,,,,,,,
-BTN_5,0x105,,,,,,,,,,,,,,,,,
-BTN_6,0x106,,,,,,,,,,,,,,,,,
-BTN_7,0x107,,,,,,,,,,,,,,,,,
-BTN_8,0x108,,,,,,,,,,,,,,,,,
-BTN_9,0x109,,,,,,,,,,,,,,,,,
-BTN_MOUSE,0x110,,,,,,,,,,,,,,,,,
-BTN_LEFT,0x110,,,,,,,,,,,,,,,,,
-BTN_RIGHT,0x111,,,,,,,,,,,,,,,,,
-BTN_MIDDLE,0x112,,,,,,,,,,,,,,,,,
-BTN_SIDE,0x113,,,,,,,,,,,,,,,,,
-BTN_EXTRA,0x114,,,,,,,,,,,,,,,,,
-BTN_FORWARD,0x115,,,,,,,,,,,,,,,,,
-BTN_BACK,0x116,,,,,,,,,,,,,,,,,
-BTN_TASK,0x117,,,,,,,,,,,,,,,,,
-BTN_JOYSTICK,0x120,,,,,,,,,,,,,,,,,
-BTN_TRIGGER,0x120,,,,,,,,,,,,,,,,,
-BTN_THUMB,0x121,,,,,,,,,,,,,,,,,
-BTN_THUMB2,0x122,,,,,,,,,,,,,,,,,
-BTN_TOP,0x123,,,,,,,,,,,,,,,,,
-BTN_TOP2,0x124,,,,,,,,,,,,,,,,,
-BTN_PINKIE,0x125,,,,,,,,,,,,,,,,,
-BTN_BASE,0x126,,,,,,,,,,,,,,,,,
-BTN_BASE2,0x127,,,,,,,,,,,,,,,,,
-BTN_BASE3,0x128,,,,,,,,,,,,,,,,,
-BTN_BASE4,0x129,,,,,,,,,,,,,,,,,
-BTN_BASE5,0x12a,,,,,,,,,,,,,,,,,
-BTN_BASE6,0x12b,,,,,,,,,,,,,,,,,
-BTN_DEAD,0x12f,,,,,,,,,,,,,,,,,
-BTN_GAMEPAD,0x130,,,,,,,,,,,,,,,,,
-BTN_A,0x130,,,,,,,,,,,,,,,,,
-BTN_B,0x131,,,,,,,,,,,,,,,,,
-BTN_C,0x132,,,,,,,,,,,,,,,,,
-BTN_X,0x133,,,,,,,,,,,,,,,,,
-BTN_Y,0x134,,,,,,,,,,,,,,,,,
-BTN_Z,0x135,,,,,,,,,,,,,,,,,
-BTN_TL,0x136,,,,,,,,,,,,,,,,,
-BTN_TR,0x137,,,,,,,,,,,,,,,,,
-BTN_TL2,0x138,,,,,,,,,,,,,,,,,
-BTN_TR2,0x139,,,,,,,,,,,,,,,,,
-BTN_SELECT,0x13a,,,,,,,,,,,,,,,,,
-BTN_START,0x13b,,,,,,,,,,,,,,,,,
-BTN_MODE,0x13c,,,,,,,,,,,,,,,,,
-BTN_THUMBL,0x13d,,,,,,,,,,,,,,,,,
-BTN_THUMBR,0x13e,,,,,,,,,,,,,,,,,
-BTN_DIGI,0x140,,,,,,,,,,,,,,,,,
-BTN_TOOL_PEN,0x140,,,,,,,,,,,,,,,,,
-BTN_TOOL_RUBBER,0x141,,,,,,,,,,,,,,,,,
-BTN_TOOL_BRUSH,0x142,,,,,,,,,,,,,,,,,
-BTN_TOOL_PENCIL,0x143,,,,,,,,,,,,,,,,,
-BTN_TOOL_AIRBRUSH,0x144,,,,,,,,,,,,,,,,,
-BTN_TOOL_FINGER,0x145,,,,,,,,,,,,,,,,,
-BTN_TOOL_MOUSE,0x146,,,,,,,,,,,,,,,,,
-BTN_TOOL_LENS,0x147,,,,,,,,,,,,,,,,,
-BTN_TOUCH,0x14a,,,,,,,,,,,,,,,,,
-BTN_STYLUS,0x14b,,,,,,,,,,,,,,,,,
-BTN_STYLUS2,0x14c,,,,,,,,,,,,,,,,,
-BTN_TOOL_DOUBLETAP,0x14d,,,,,,,,,,,,,,,,,
-BTN_TOOL_TRIPLETAP,0x14e,,,,,,,,,,,,,,,,,
-BTN_TOOL_QUADTAP,0x14f,,,,,,,,,,,,,,,,,
-BTN_WHEEL,0x150,,,,,,,,,,,,,,,,,
-BTN_GEAR_DOWN,0x150,,,,,,,,,,,,,,,,,
-BTN_GEAR_UP,0x151,,,,,,,,,,,,,,,,,
-KEY_OK,0x160,,,,,,,,,,,,,,,,,
-KEY_SELECT,0x161,,,,,,,VK_SELECT,0x29,,,XK_Select,0xff60,Select,SELE,,,
-KEY_GOTO,0x162,,,,,,,,,,,,,,,,,
-KEY_CLEAR,0x163,,,,,,,,,,,,,NumpadClear,CLR,,,
-KEY_POWER2,0x164,,,,,,,,,,,,,,,,,
-KEY_OPTION,0x165,,,,,,,,,,,,,,,,,
-KEY_INFO,0x166,,,,,,,,,,,,,,,,,
-KEY_TIME,0x167,,,,,,,,,,,,,,,,,
-KEY_VENDOR,0x168,,,,,,,,,,,,,,,,,
-KEY_ARCHIVE,0x169,,,,,,,,,,,,,,,,,
-KEY_PROGRAM,0x16a,,,,,,,,,,,,,,,,,
-KEY_CHANNEL,0x16b,,,,,,,,,,,,,,,,,
-KEY_FAVORITES,0x16c,,,,,,,VK_BROWSER_FAVOURITES,0xab,,,,,,,,,
-KEY_EPG,0x16d,,,,,,,,,,,,,,,,,
-KEY_PVR,0x16e,,,,,,,,,,,,,,,,,
-KEY_MHP,0x16f,,,,,,,,,,,,,,,,,
-KEY_LANGUAGE,0x170,,,,,,,,,,,,,,,,,
-KEY_TITLE,0x171,,,,,,,,,,,,,,,,,
-KEY_SUBTITLE,0x172,,,,,,,,,,,,,,,,,
-KEY_ANGLE,0x173,,,,,,,,,,,,,,,,,
-KEY_ZOOM,0x174,,,,,,,VK_ZOOM,0xfb,,,,,,,,,
-KEY_MODE,0x175,,,,,,,,,,,,,,,,,
-KEY_KEYBOARD,0x176,,,,,,,,,,,,,,,,,
-KEY_SCREEN,0x177,,,,,,,,,,,,,,,,,
-KEY_PC,0x178,,,,,,,,,,,,,,,,,
-KEY_TV,0x179,,,,,,,,,,,,,,,,,
-KEY_TV2,0x17a,,,,,,,,,,,,,,,,,
-KEY_VCR,0x17b,,,,,,,,,,,,,,,,,
-KEY_VCR2,0x17c,,,,,,,,,,,,,,,,,
-KEY_SAT,0x17d,,,,,,,,,,,,,,,,,
-KEY_SAT2,0x17e,,,,,,,,,,,,,,,,,
-KEY_CD,0x17f,,,,,,,,,,,,,,,,,
-KEY_TAPE,0x180,,,,,,,,,,,,,,,,,
-KEY_RADIO,0x181,,,,,,,,,,,,,,,,,
-KEY_TUNER,0x182,,,,,,,,,,,,,,,,,
-KEY_PLAYER,0x183,,,,,,,,,,,,,,,,,
-KEY_TEXT,0x184,,,,,,,,,,,,,,,,,
-KEY_DVD,0x185,,,,,,,,,,,,,,,,,
-KEY_AUX,0x186,,,,,,,,,,,,,,,,,
-KEY_MP3,0x187,,,,,,,,,,,,,,,,,
-KEY_AUDIO,0x188,,,,,,,,,,,,,,,,,
-KEY_VIDEO,0x189,,,,,,,,,,,,,,,,,
-KEY_DIRECTORY,0x18a,,,,,,,,,,,,,,,,,
-KEY_LIST,0x18b,,,,,,,,,,,,,,,,,
-KEY_MEMO,0x18c,,,,,,,,,,,,,,,,,
-KEY_CALENDAR,0x18d,,,,,,,,,,,,,,,,,
-KEY_RED,0x18e,,,,,,,,,,,,,,,,,
-KEY_GREEN,0x18f,,,,,,,,,,,,,,,,,
-KEY_YELLOW,0x190,,,,,,,,,,,,,,,,,
-KEY_BLUE,0x191,,,,,,,,,,,,,,,,,
-KEY_CHANNELUP,0x192,,,,,,,,,,,,,,,,,
-KEY_CHANNELDOWN,0x193,,,,,,,,,,,,,,,,,
-KEY_FIRST,0x194,,,,,,,,,,,,,,,,,
-KEY_LAST,0x195,,,,,,,,,,,,,,,,,
-KEY_AB,0x196,,,,,,,,,,,,,,,,,
-KEY_NEXT,0x197,,,,,,,,,,,,,,,,,
-KEY_RESTART,0x198,,,,,,,,,,,,,,,,,
-KEY_SLOW,0x199,,,,,,,,,,,,,,,,,
-KEY_SHUFFLE,0x19a,,,,,,,,,,,,,,,,,
-KEY_BREAK,0x19b,,,,,,,,,,,,,,BREA,,,
-KEY_BREAK,0x19b,,,,,,,,,,,,,,BRK,,,
-KEY_PREVIOUS,0x19c,,,,,,,,,,,,,,,,,
-KEY_DIGITS,0x19d,,,,,,,,,,,,,,,,,
-KEY_TEEN,0x19e,,,,,,,,,,,,,,,,,
-KEY_TWEN,0x19f,,,,,,,,,,,,,,,,,
-KEY_VIDEOPHONE,0x1a0,,,,,,,,,,,,,,,,,
-KEY_GAMES,0x1a1,,,,,,,,,,,,,,,,,
-KEY_ZOOMIN,0x1a2,,,,,,,,,,,,,,,,,
-KEY_ZOOMOUT,0x1a3,,,,,,,,,,,,,,,,,
-KEY_ZOOMRESET,0x1a4,,,,,,,,,,,,,,,,,
-KEY_WORDPROCESSOR,0x1a5,,,,,,,,,,,,,,,,,
-KEY_EDITOR,0x1a6,,,,,,,,,,,,,,,,,
-KEY_SPREADSHEET,0x1a7,,,,,,,,,,,,,,,,,
-KEY_GRAPHICSEDITOR,0x1a8,,,,,,,,,,,,,,,,,
-KEY_PRESENTATION,0x1a9,,,,,,,,,,,,,,,,,
-KEY_DATABASE,0x1aa,,,,,,,,,,,,,,,,,
-KEY_NEWS,0x1ab,,,,,,,,,,,,,,,,,
-KEY_VOICEMAIL,0x1ac,,,,,,,,,,,,,,,,,
-KEY_ADDRESSBOOK,0x1ad,,,,,,,,,,,,,,,,,
-KEY_MESSENGER,0x1ae,,,,,,,,,,,,,,,,,
-KEY_DISPLAYTOGGLE,0x1af,,,,,,,,,,,,,,,,,
-KEY_SPELLCHECK,0x1b0,,,,,,,,,,,,,,,,,
-KEY_LOGOFF,0x1b1,,,,,,,,,,,,,,,,,
-KEY_DOLLAR,0x1b2,,,,,,,,,,,,,,,,,
-KEY_EURO,0x1b3,,,,,,,,,,,,,,,,,
-KEY_FRAMEBACK,0x1b4,,,,,,,,,,,,,,,,,
-KEY_FRAMEFORWARD,0x1b5,,,,,,,,,,,,,,,,,
-KEY_CONTEXT_MENU,0x1b6,,,,,,,,,,,,,,,,,
-KEY_MEDIA_REPEAT,0x1b7,,,,,,,,,,,,,,,,,
-KEY_DEL_EOL,0x1c0,,,,,,,,,,,,,,,,,
-KEY_DEL_EOS,0x1c1,,,,,,,,,,,,,,,,,
-KEY_INS_LINE,0x1c2,,,,,,,,,,,,,,,,,
-KEY_DEL_LINE,0x1c3,,,,,,,,,,,,,,,,,
-KEY_FN,0x1d0,Function,0x3f,,,,,,,,,,,Fn,,,,
-KEY_FN_ESC,0x1d1,,,,,,,,,,,,,,,,,
-KEY_FN_F1,0x1d2,,,,,,,,,,,,,,,,,
-KEY_FN_F2,0x1d3,,,,,,,,,,,,,,,,,
-KEY_FN_F3,0x1d4,,,,,,,,,,,,,,,,,
-KEY_FN_F4,0x1d5,,,,,,,,,,,,,,,,,
-KEY_FN_F5,0x1d6,,,,,,,,,,,,,,,,,
-KEY_FN_F6,0x1d7,,,,,,,,,,,,,,,,,
-KEY_FN_F7,0x1d8,,,,,,,,,,,,,,,,,
-KEY_FN_F8,0x1d9,,,,,,,,,,,,,,,,,
-KEY_FN_F9,0x1da,,,,,,,,,,,,,,,,,
-KEY_FN_F10,0x1db,,,,,,,,,,,,,,,,,
-KEY_FN_F11,0x1dc,,,,,,,,,,,,,,,,,
-KEY_FN_F12,0x1dd,,,,,,,,,,,,,,,,,
-KEY_FN_1,0x1de,,,,,,,,,,,,,,,,,
-KEY_FN_2,0x1df,,,,,,,,,,,,,,,,,
-KEY_FN_D,0x1e0,,,,,,,,,,,,,,,,,
-KEY_FN_E,0x1e1,,,,,,,,,,,,,,,,,
-KEY_FN_F,0x1e2,,,,,,,,,,,,,,,,,
-KEY_FN_S,0x1e3,,,,,,,,,,,,,,,,,
-KEY_FN_B,0x1e4,,,,,,,,,,,,,,,,,
-KEY_BRL_DOT1,0x1f1,,,,,,,,,,,,,,,,,
-KEY_BRL_DOT2,0x1f2,,,,,,,,,,,,,,,,,
-KEY_BRL_DOT3,0x1f3,,,,,,,,,,,,,,,,,
-KEY_BRL_DOT4,0x1f4,,,,,,,,,,,,,,,,,
-KEY_BRL_DOT5,0x1f5,,,,,,,,,,,,,,,,,
-KEY_BRL_DOT6,0x1f6,,,,,,,,,,,,,,,,,
-KEY_BRL_DOT7,0x1f7,,,,,,,,,,,,,,,,,
-KEY_BRL_DOT8,0x1f8,,,,,,,,,,,,,,,,,
-KEY_BRL_DOT9,0x1f9,,,,,,,,,,,,,,,,,
-KEY_BRL_DOT10,0x1fa,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_0,0x200,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_1,0x201,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_2,0x202,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_3,0x203,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_4,0x204,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_5,0x205,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_6,0x206,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_7,0x207,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_8,0x208,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_9,0x209,,,,,,,,,,,,,,,,,
-KEY_NUMERIC_STAR,0x20a,,,,,,,,,,,,,NumpadStar,,,,
-KEY_NUMERIC_POUND,0x20b,,,,,,,,,,,,,NumpadHash,,,,
-KEY_RFKILL,0x20c,,,,,,,,,,,,,,,,,
diff --git a/keycodemapdb/meson.build b/keycodemapdb/meson.build
deleted file mode 100644
index eb9416b..0000000
--- a/keycodemapdb/meson.build
+++ /dev/null
@@ -1 +0,0 @@
-project('keycodemapdb')
diff --git a/keycodemapdb/tests/.gitignore b/keycodemapdb/tests/.gitignore
deleted file mode 100644
index 0562305..0000000
--- a/keycodemapdb/tests/.gitignore
+++ /dev/null
@@ -1,11 +0,0 @@
-osx2win32.*
-osx2win32_name.*
-osx2xkb.*
-osx2xkb_name.*
-html2win32.*
-html2win32_name.*
-osx.*
-osx_name.*
-stdc
-stdc++
-node_modules/
diff --git a/keycodemapdb/tests/Makefile b/keycodemapdb/tests/Makefile
deleted file mode 100644
index e1b3875..0000000
--- a/keycodemapdb/tests/Makefile
+++ /dev/null
@@ -1,150 +0,0 @@
-TESTS := stdc stdc++ python2 python3 javascript
-
-check: $(TESTS)
- @set -e; for fn in $(TESTS); do \
- ./$$fn; \
- echo $$fn: OK; \
- done
- @echo Done.
-
-GEN := ../tools/keymap-gen
-DATA := ../data/keymaps.csv
-SOURCES := $(GEN) $(DATA)
-
-.DELETE_ON_ERROR:
-
-stdc: stdc.c osx2win32.h osx2win32.c osx2win32_name.h osx2win32_name.c \
- osx2xkb.h osx2xkb.c osx2xkb_name.h osx2xkb_name.c \
- html2win32.h html2win32.c html2win32_name.h html2win32_name.c \
- osx.h osx.c osx_name.h osx_name.c
- $(CC) -Wall -o $@ $(filter %.c, $^)
-osx2win32.c: $(SOURCES)
- $(GEN) --lang stdc code-map $(DATA) osx win32 > $@
-osx2win32.h: $(SOURCES)
- $(GEN) --lang stdc-header code-map $(DATA) osx win32 > $@
-osx2win32_name.c: $(SOURCES)
- $(GEN) --lang stdc name-map $(DATA) osx win32 > $@
-osx2win32_name.h: $(SOURCES)
- $(GEN) --lang stdc-header name-map $(DATA) osx win32 > $@
-osx2xkb.c: $(SOURCES)
- $(GEN) --lang stdc code-map $(DATA) osx xkb > $@
-osx2xkb.h: $(SOURCES)
- $(GEN) --lang stdc-header code-map $(DATA) osx xkb > $@
-osx2xkb_name.c: $(SOURCES)
- $(GEN) --lang stdc name-map $(DATA) osx xkb > $@
-osx2xkb_name.h: $(SOURCES)
- $(GEN) --lang stdc-header name-map $(DATA) osx xkb > $@
-html2win32.c: $(SOURCES)
- $(GEN) --lang stdc code-map $(DATA) html win32 > $@
-html2win32.h: $(SOURCES)
- $(GEN) --lang stdc-header code-map $(DATA) html win32 > $@
-html2win32_name.c: $(SOURCES)
- $(GEN) --lang stdc name-map $(DATA) html win32 > $@
-html2win32_name.h: $(SOURCES)
- $(GEN) --lang stdc-header name-map $(DATA) html win32 > $@
-osx.c: $(SOURCES)
- $(GEN) --lang stdc code-table $(DATA) osx > $@
-osx.h: $(SOURCES)
- $(GEN) --lang stdc-header code-table $(DATA) osx > $@
-osx_name.c: $(SOURCES)
- $(GEN) --lang stdc name-table $(DATA) osx > $@
-osx_name.h: $(SOURCES)
- $(GEN) --lang stdc-header name-table $(DATA) osx > $@
-
-stdc++: stdc++.cc osx2win32.hh osx2win32.cc osx2win32_name.hh osx2win32_name.cc \
- osx2xkb.hh osx2xkb.cc osx2xkb_name.hh osx2xkb_name.cc \
- html2win32.hh html2win32.cc html2win32_name.hh html2win32_name.cc \
- osx.hh osx.cc osx_name.hh osx_name.cc
- $(CXX) -Wall -std=c++11 -o $@ $(filter %.cc, $^)
-osx2win32.cc: $(SOURCES)
- $(GEN) --lang stdc++ code-map $(DATA) osx win32 > $@
-osx2win32.hh: $(SOURCES)
- $(GEN) --lang stdc++-header code-map $(DATA) osx win32 > $@
-osx2win32_name.cc: $(SOURCES)
- $(GEN) --lang stdc++ name-map $(DATA) osx win32 > $@
-osx2win32_name.hh: $(SOURCES)
- $(GEN) --lang stdc++-header name-map $(DATA) osx win32 > $@
-osx2xkb.cc: $(SOURCES)
- $(GEN) --lang stdc++ code-map $(DATA) osx xkb > $@
-osx2xkb.hh: $(SOURCES)
- $(GEN) --lang stdc++-header code-map $(DATA) osx xkb > $@
-osx2xkb_name.cc: $(SOURCES)
- $(GEN) --lang stdc++ name-map $(DATA) osx xkb > $@
-osx2xkb_name.hh: $(SOURCES)
- $(GEN) --lang stdc++-header name-map $(DATA) osx xkb > $@
-html2win32.cc: $(SOURCES)
- $(GEN) --lang stdc++ code-map $(DATA) html win32 > $@
-html2win32.hh: $(SOURCES)
- $(GEN) --lang stdc++-header code-map $(DATA) html win32 > $@
-html2win32_name.cc: $(SOURCES)
- $(GEN) --lang stdc++ name-map $(DATA) html win32 > $@
-html2win32_name.hh: $(SOURCES)
- $(GEN) --lang stdc++-header name-map $(DATA) html win32 > $@
-osx.cc: $(SOURCES)
- $(GEN) --lang stdc++ code-table $(DATA) osx > $@
-osx.hh: $(SOURCES)
- $(GEN) --lang stdc++-header code-table $(DATA) osx > $@
-osx_name.cc: $(SOURCES)
- $(GEN) --lang stdc++ name-table $(DATA) osx > $@
-osx_name.hh: $(SOURCES)
- $(GEN) --lang stdc++-header name-table $(DATA) osx > $@
-
-python2: osx2win32.py osx2win32_name.py \
- osx2xkb.py osx2xkb_name.py \
- html2win32.py html2win32_name.py \
- osx.py osx_name.py
-osx2win32.py: $(SOURCES)
- $(GEN) --lang python2 code-map $(DATA) osx win32 > $@
-osx2win32_name.py: $(SOURCES)
- $(GEN) --lang python2 name-map $(DATA) osx win32 > $@
-osx2xkb.py: $(SOURCES)
- $(GEN) --lang python2 code-map $(DATA) osx xkb > $@
-osx2xkb_name.py: $(SOURCES)
- $(GEN) --lang python2 name-map $(DATA) osx xkb > $@
-html2win32.py: $(SOURCES)
- $(GEN) --lang python2 code-map $(DATA) html win32 > $@
-html2win32_name.py: $(SOURCES)
- $(GEN) --lang python2 name-map $(DATA) html win32 > $@
-osx.py: $(SOURCES)
- $(GEN) --lang python2 code-table $(DATA) osx > $@
-osx_name.py: $(SOURCES)
- $(GEN) --lang python2 name-table $(DATA) osx > $@
-
-javascript: node_modules/babel-core \
- node_modules/babel-plugin-transform-es2015-modules-commonjs \
- osx2win32.js osx2win32_name.js \
- osx2xkb.js osx2xkb_name.js \
- html2win32.js html2win32_name.js \
- osx.js osx_name.js
-node_modules/babel-core:
- npm install babel-core
-node_modules/babel-plugin-transform-es2015-modules-commonjs:
- npm install babel-plugin-transform-es2015-modules-commonjs
-osx2win32.js: $(SOURCES)
- $(GEN) --lang js code-map $(DATA) osx win32 > $@
-osx2win32_name.js: $(SOURCES)
- $(GEN) --lang js name-map $(DATA) osx win32 > $@
-osx2xkb.js: $(SOURCES)
- $(GEN) --lang js code-map $(DATA) osx xkb > $@
-osx2xkb_name.js: $(SOURCES)
- $(GEN) --lang js name-map $(DATA) osx xkb > $@
-html2win32.js: $(SOURCES)
- $(GEN) --lang js code-map $(DATA) html win32 > $@
-html2win32_name.js: $(SOURCES)
- $(GEN) --lang js name-map $(DATA) html win32 > $@
-osx.js: $(SOURCES)
- $(GEN) --lang js code-table $(DATA) osx > $@
-osx_name.js: $(SOURCES)
- $(GEN) --lang js name-table $(DATA) osx > $@
-
-clean:
- rm -rf node_modules
- rm -f osx2win32.*
- rm -f osx2win32_name.*
- rm -f osx2xkb.*
- rm -f osx2xkb_name.*
- rm -f html2win32.*
- rm -f html2win32_name.*
- rm -f osx.*
- rm -f osx_name.*
- rm -f stdc stdc++
diff --git a/keycodemapdb/tests/javascript b/keycodemapdb/tests/javascript
deleted file mode 100755
index 5179db2..0000000
--- a/keycodemapdb/tests/javascript
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env node
-/*
- * Keycode Map Generator JavaScript Tests
- *
- * Copyright 2017 Pierre Ossman for Cendio AB
- *
- * This file is dual license under the terms of the GPLv2 or later
- * and 3-clause BSD licenses.
- */
-
-"use strict";
-
-var assert = require('assert');
-var babel = require('babel-core');
-var fs = require('fs');
-
-function include(fn) {
- var options = {
- plugins: ["transform-es2015-modules-commonjs"]
- };
-
- var code = babel.transformFileSync(fn, options).code;
- fs.writeFileSync("." + fn + "_nodejs.js", code);
- var imp = require("./." + fn + "_nodejs.js");
- fs.unlinkSync("./." + fn + "_nodejs.js");
-
- return imp
-}
-
-var code_map_osx_to_win32 = include("osx2win32.js").default;
-var name_map_osx_to_win32 = include("osx2win32_name.js").default;
-
-var code_map_osx_to_xkb = include("osx2xkb.js").default;
-var name_map_osx_to_xkb = include("osx2xkb_name.js").default;
-
-var code_map_html_to_win32 = include("html2win32.js").default;
-var name_map_html_to_win32 = include("html2win32_name.js").default;
-
-var code_table_osx = include("osx.js").default;
-var name_table_osx = include("osx_name.js").default;
-
-assert.equal(code_map_osx_to_win32[0x1d], 0x30);
-assert.equal(name_map_osx_to_win32[0x1d], "VK_0");
-
-assert.equal(code_map_osx_to_xkb[0x1d], "AE10");
-assert.equal(name_map_osx_to_xkb[0x1d], "AE10");
-
-assert.equal(code_map_html_to_win32["ControlLeft"], 0x11);
-assert.equal(name_map_html_to_win32["ControlLeft"], "VK_CONTROL");
-
-assert.equal(code_table_osx[0x1d], 0x3b);
-assert.equal(name_table_osx[0x1d], "Control");
-
diff --git a/keycodemapdb/tests/python2 b/keycodemapdb/tests/python2
deleted file mode 100755
index 28a5b03..0000000
--- a/keycodemapdb/tests/python2
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-python ./test.py
diff --git a/keycodemapdb/tests/python3 b/keycodemapdb/tests/python3
deleted file mode 100755
index ded1f68..0000000
--- a/keycodemapdb/tests/python3
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-python3 ./test.py
diff --git a/keycodemapdb/tests/stdc++.cc b/keycodemapdb/tests/stdc++.cc
deleted file mode 100644
index 5e3e8f5..0000000
--- a/keycodemapdb/tests/stdc++.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Keycode Map Generator C++ Tests
- *
- * Copyright 2017 Pierre Ossman for Cendio AB
- *
- * This file is dual license under the terms of the GPLv2 or later
- * and 3-clause BSD licenses.
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include "osx2win32.hh"
-#include "osx2win32_name.hh"
-
-#include "osx2xkb.hh"
-#include "osx2xkb_name.hh"
-
-#include "html2win32.hh"
-#include "html2win32_name.hh"
-
-#include "osx.hh"
-#include "osx_name.hh"
-
-int main(int argc, char** argv)
-{
- assert(code_map_osx_to_win32[0x1d] == 0x30);
- assert(strcmp(name_map_osx_to_win32[0x1d], "VK_0") == 0);
-
- assert(strcmp(code_map_osx_to_xkb[0x1d], "AE10") == 0);
- assert(strcmp(name_map_osx_to_xkb[0x1d], "AE10") == 0);
-
- assert(code_map_html_to_win32.at("ControlLeft") == 0x11);
- assert(strcmp(name_map_html_to_win32.at("ControlLeft"), "VK_CONTROL") == 0);
-
- assert(code_table_osx[0x1d] == 0x3b);
- assert(strcmp(name_table_osx[0x1d], "Control") == 0);
-
- return 0;
-}
diff --git a/keycodemapdb/tests/stdc.c b/keycodemapdb/tests/stdc.c
deleted file mode 100644
index e4946fa..0000000
--- a/keycodemapdb/tests/stdc.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Keycode Map Generator C Tests
- *
- * Copyright 2017 Pierre Ossman for Cendio AB
- *
- * This file is dual license under the terms of the GPLv2 or later
- * and 3-clause BSD licenses.
- */
-
-#include <assert.h>
-#include <string.h>
-
-#include "osx2win32.h"
-#include "osx2win32_name.h"
-
-#include "osx2xkb.h"
-#include "osx2xkb_name.h"
-
-#include "html2win32.h"
-#include "html2win32_name.h"
-
-#include "osx.h"
-#include "osx_name.h"
-
-#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
-
-int main(int argc, char** argv)
-{
- unsigned i;
-
- assert(code_map_osx_to_win32_len == ARRAY_SIZE(code_map_osx_to_win32));
- assert(code_map_osx_to_win32[0x1d] == 0x30);
- assert(name_map_osx_to_win32_len == ARRAY_SIZE(name_map_osx_to_win32));
- assert(strcmp(name_map_osx_to_win32[0x1d], "VK_0") == 0);
-
- assert(code_map_osx_to_xkb_len == ARRAY_SIZE(code_map_osx_to_xkb));
- assert(strcmp(code_map_osx_to_xkb[0x1d], "AE10") == 0);
- assert(name_map_osx_to_xkb_len == ARRAY_SIZE(name_map_osx_to_xkb));
- assert(strcmp(name_map_osx_to_xkb[0x1d], "AE10") == 0);
-
- assert(code_map_html_to_win32_len == ARRAY_SIZE(code_map_html_to_win32));
- for (i = 0;i < code_map_html_to_win32_len;i++) {
- if (strcmp(code_map_html_to_win32[i].from, "ControlLeft") == 0) {
- assert(code_map_html_to_win32[i].to == 0x11);
- break;
- }
- }
- assert(i != code_map_html_to_win32_len);
- assert(name_map_html_to_win32_len == ARRAY_SIZE(name_map_html_to_win32));
- for (i = 0;i < name_map_html_to_win32_len;i++) {
- if (strcmp(name_map_html_to_win32[i].from, "ControlLeft") == 0) {
- assert(strcmp(name_map_html_to_win32[i].to, "VK_CONTROL") == 0);
- break;
- }
- }
- assert(i != name_map_html_to_win32_len);
-
- assert(code_table_osx_len == ARRAY_SIZE(code_table_osx));
- assert(code_table_osx[0x1d] == 0x3b);
- assert(name_table_osx_len == ARRAY_SIZE(name_table_osx));
- assert(strcmp(name_table_osx[0x1d], "Control") == 0);
-
- return 0;
-}
diff --git a/keycodemapdb/tests/test.py b/keycodemapdb/tests/test.py
deleted file mode 100644
index f265145..0000000
--- a/keycodemapdb/tests/test.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Keycode Map Generator Python Tests
-#
-# Copyright 2017 Pierre Ossman for Cendio AB
-#
-# This file is dual license under the terms of the GPLv2 or later
-# and 3-clause BSD licenses.
-
-import osx2win32
-import osx2win32_name
-
-import osx2xkb
-import osx2xkb_name
-
-import html2win32
-import html2win32_name
-
-import osx
-import osx_name
-
-assert osx2win32.code_map_osx_to_win32[0x1d] == 0x30
-assert osx2win32_name.name_map_osx_to_win32[0x1d] == "VK_0"
-
-assert osx2xkb.code_map_osx_to_xkb[0x1d] == "AE10"
-assert osx2xkb_name.name_map_osx_to_xkb[0x1d] == "AE10"
-
-assert html2win32.code_map_html_to_win32["ControlLeft"] == 0x11
-assert html2win32_name.name_map_html_to_win32["ControlLeft"] == "VK_CONTROL"
-
-assert osx.code_table_osx[0x1d] == 0x3b;
-assert osx_name.name_table_osx[0x1d] == "Control";
diff --git a/keycodemapdb/thirdparty/LICENSE-argparse.txt b/keycodemapdb/thirdparty/LICENSE-argparse.txt
deleted file mode 100644
index 640bc78..0000000
--- a/keycodemapdb/thirdparty/LICENSE-argparse.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-argparse is (c) 2006-2009 Steven J. Bethard <steven.bethard at gmail.com>.
-
-The argparse module was contributed to Python as of Python 2.7 and thus
-was licensed under the Python license. Same license applies to all files in
-the argparse package project.
-
-For details about the Python License, please see doc/Python-License.txt.
-
-History
--------
-
-Before (and including) argparse 1.1, the argparse package was licensed under
-Apache License v2.0.
-
-After argparse 1.1, all project files from the argparse project were deleted
-due to license compatibility issues between Apache License 2.0 and GNU GPL v2.
-
-The project repository then had a clean start with some files taken from
-Python 2.7.1, so definitely all files are under Python License now.
-
diff --git a/keycodemapdb/thirdparty/__init__.py b/keycodemapdb/thirdparty/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/keycodemapdb/thirdparty/argparse.py b/keycodemapdb/thirdparty/argparse.py
deleted file mode 100644
index 70a77cc..0000000
--- a/keycodemapdb/thirdparty/argparse.py
+++ /dev/null
@@ -1,2392 +0,0 @@
-# Author: Steven J. Bethard <steven.bethard at gmail.com>.
-# Maintainer: Thomas Waldmann <tw at waldmann-edv.de>
-
-"""Command-line parsing library
-
-This module is an optparse-inspired command-line parsing library that:
-
- - handles both optional and positional arguments
- - produces highly informative usage messages
- - supports parsers that dispatch to sub-parsers
-
-The following is a simple usage example that sums integers from the
-command-line and writes the result to a file::
-
- parser = argparse.ArgumentParser(
- description='sum the integers at the command line')
- parser.add_argument(
- 'integers', metavar='int', nargs='+', type=int,
- help='an integer to be summed')
- parser.add_argument(
- '--log', default=sys.stdout, type=argparse.FileType('w'),
- help='the file where the sum should be written')
- args = parser.parse_args()
- args.log.write('%s' % sum(args.integers))
- args.log.close()
-
-The module contains the following public classes:
-
- - ArgumentParser -- The main entry point for command-line parsing. As the
- example above shows, the add_argument() method is used to populate
- the parser with actions for optional and positional arguments. Then
- the parse_args() method is invoked to convert the args at the
- command-line into an object with attributes.
-
- - ArgumentError -- The exception raised by ArgumentParser objects when
- there are errors with the parser's actions. Errors raised while
- parsing the command-line are caught by ArgumentParser and emitted
- as command-line messages.
-
- - FileType -- A factory for defining types of files to be created. As the
- example above shows, instances of FileType are typically passed as
- the type= argument of add_argument() calls.
-
- - Action -- The base class for parser actions. Typically actions are
- selected by passing strings like 'store_true' or 'append_const' to
- the action= argument of add_argument(). However, for greater
- customization of ArgumentParser actions, subclasses of Action may
- be defined and passed as the action= argument.
-
- - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
- ArgumentDefaultsHelpFormatter -- Formatter classes which
- may be passed as the formatter_class= argument to the
- ArgumentParser constructor. HelpFormatter is the default,
- RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
- not to change the formatting for help text, and
- ArgumentDefaultsHelpFormatter adds information about argument defaults
- to the help.
-
-All other classes in this module are considered implementation details.
-(Also note that HelpFormatter and RawDescriptionHelpFormatter are only
-considered public as object names -- the API of the formatter objects is
-still considered an implementation detail.)
-"""
-
-__version__ = '1.4.0' # we use our own version number independant of the
- # one in stdlib and we release this on pypi.
-
-__external_lib__ = True # to make sure the tests really test THIS lib,
- # not the builtin one in Python stdlib
-
-__all__ = [
- 'ArgumentParser',
- 'ArgumentError',
- 'ArgumentTypeError',
- 'FileType',
- 'HelpFormatter',
- 'ArgumentDefaultsHelpFormatter',
- 'RawDescriptionHelpFormatter',
- 'RawTextHelpFormatter',
- 'Namespace',
- 'Action',
- 'ONE_OR_MORE',
- 'OPTIONAL',
- 'PARSER',
- 'REMAINDER',
- 'SUPPRESS',
- 'ZERO_OR_MORE',
-]
-
-
-import copy as _copy
-import os as _os
-import re as _re
-import sys as _sys
-import textwrap as _textwrap
-
-from gettext import gettext as _
-
-try:
- set
-except NameError:
- # for python < 2.4 compatibility (sets module is there since 2.3):
- from sets import Set as set
-
-try:
- basestring
-except NameError:
- basestring = str
-
-try:
- sorted
-except NameError:
- # for python < 2.4 compatibility:
- def sorted(iterable, reverse=False):
- result = list(iterable)
- result.sort()
- if reverse:
- result.reverse()
- return result
-
-
-def _callable(obj):
- return hasattr(obj, '__call__') or hasattr(obj, '__bases__')
-
-
-SUPPRESS = '==SUPPRESS=='
-
-OPTIONAL = '?'
-ZERO_OR_MORE = '*'
-ONE_OR_MORE = '+'
-PARSER = 'A...'
-REMAINDER = '...'
-_UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
-
-# =============================
-# Utility functions and classes
-# =============================
-
-class _AttributeHolder(object):
- """Abstract base class that provides __repr__.
-
- The __repr__ method returns a string in the format::
- ClassName(attr=name, attr=name, ...)
- The attributes are determined either by a class-level attribute,
- '_kwarg_names', or by inspecting the instance __dict__.
- """
-
- def __repr__(self):
- type_name = type(self).__name__
- arg_strings = []
- for arg in self._get_args():
- arg_strings.append(repr(arg))
- for name, value in self._get_kwargs():
- arg_strings.append('%s=%r' % (name, value))
- return '%s(%s)' % (type_name, ', '.join(arg_strings))
-
- def _get_kwargs(self):
- return sorted(self.__dict__.items())
-
- def _get_args(self):
- return []
-
-
-def _ensure_value(namespace, name, value):
- if getattr(namespace, name, None) is None:
- setattr(namespace, name, value)
- return getattr(namespace, name)
-
-
-# ===============
-# Formatting Help
-# ===============
-
-class HelpFormatter(object):
- """Formatter for generating usage messages and argument help strings.
-
- Only the name of this class is considered a public API. All the methods
- provided by the class are considered an implementation detail.
- """
-
- def __init__(self,
- prog,
- indent_increment=2,
- max_help_position=24,
- width=None):
-
- # default setting for width
- if width is None:
- try:
- width = int(_os.environ['COLUMNS'])
- except (KeyError, ValueError):
- width = 80
- width -= 2
-
- self._prog = prog
- self._indent_increment = indent_increment
- self._max_help_position = max_help_position
- self._width = width
-
- self._current_indent = 0
- self._level = 0
- self._action_max_length = 0
-
- self._root_section = self._Section(self, None)
- self._current_section = self._root_section
-
- self._whitespace_matcher = _re.compile(r'\s+')
- self._long_break_matcher = _re.compile(r'\n\n\n+')
-
- # ===============================
- # Section and indentation methods
- # ===============================
- def _indent(self):
- self._current_indent += self._indent_increment
- self._level += 1
-
- def _dedent(self):
- self._current_indent -= self._indent_increment
- assert self._current_indent >= 0, 'Indent decreased below 0.'
- self._level -= 1
-
- class _Section(object):
-
- def __init__(self, formatter, parent, heading=None):
- self.formatter = formatter
- self.parent = parent
- self.heading = heading
- self.items = []
-
- def format_help(self):
- # format the indented section
- if self.parent is not None:
- self.formatter._indent()
- join = self.formatter._join_parts
- for func, args in self.items:
- func(*args)
- item_help = join([func(*args) for func, args in self.items])
- if self.parent is not None:
- self.formatter._dedent()
-
- # return nothing if the section was empty
- if not item_help:
- return ''
-
- # add the heading if the section was non-empty
- if self.heading is not SUPPRESS and self.heading is not None:
- current_indent = self.formatter._current_indent
- heading = '%*s%s:\n' % (current_indent, '', self.heading)
- else:
- heading = ''
-
- # join the section-initial newline, the heading and the help
- return join(['\n', heading, item_help, '\n'])
-
- def _add_item(self, func, args):
- self._current_section.items.append((func, args))
-
- # ========================
- # Message building methods
- # ========================
- def start_section(self, heading):
- self._indent()
- section = self._Section(self, self._current_section, heading)
- self._add_item(section.format_help, [])
- self._current_section = section
-
- def end_section(self):
- self._current_section = self._current_section.parent
- self._dedent()
-
- def add_text(self, text):
- if text is not SUPPRESS and text is not None:
- self._add_item(self._format_text, [text])
-
- def add_usage(self, usage, actions, groups, prefix=None):
- if usage is not SUPPRESS:
- args = usage, actions, groups, prefix
- self._add_item(self._format_usage, args)
-
- def add_argument(self, action):
- if action.help is not SUPPRESS:
-
- # find all invocations
- get_invocation = self._format_action_invocation
- invocations = [get_invocation(action)]
- for subaction in self._iter_indented_subactions(action):
- invocations.append(get_invocation(subaction))
-
- # update the maximum item length
- invocation_length = max([len(s) for s in invocations])
- action_length = invocation_length + self._current_indent
- self._action_max_length = max(self._action_max_length,
- action_length)
-
- # add the item to the list
- self._add_item(self._format_action, [action])
-
- def add_arguments(self, actions):
- for action in actions:
- self.add_argument(action)
-
- # =======================
- # Help-formatting methods
- # =======================
- def format_help(self):
- help = self._root_section.format_help()
- if help:
- help = self._long_break_matcher.sub('\n\n', help)
- help = help.strip('\n') + '\n'
- return help
-
- def _join_parts(self, part_strings):
- return ''.join([part
- for part in part_strings
- if part and part is not SUPPRESS])
-
- def _format_usage(self, usage, actions, groups, prefix):
- if prefix is None:
- prefix = _('usage: ')
-
- # if usage is specified, use that
- if usage is not None:
- usage = usage % dict(prog=self._prog)
-
- # if no optionals or positionals are available, usage is just prog
- elif usage is None and not actions:
- usage = '%(prog)s' % dict(prog=self._prog)
-
- # if optionals and positionals are available, calculate usage
- elif usage is None:
- prog = '%(prog)s' % dict(prog=self._prog)
-
- # split optionals from positionals
- optionals = []
- positionals = []
- for action in actions:
- if action.option_strings:
- optionals.append(action)
- else:
- positionals.append(action)
-
- # build full usage string
- format = self._format_actions_usage
- action_usage = format(optionals + positionals, groups)
- usage = ' '.join([s for s in [prog, action_usage] if s])
-
- # wrap the usage parts if it's too long
- text_width = self._width - self._current_indent
- if len(prefix) + len(usage) > text_width:
-
- # break usage into wrappable parts
- part_regexp = r'\(.*?\)+|\[.*?\]+|\S+'
- opt_usage = format(optionals, groups)
- pos_usage = format(positionals, groups)
- opt_parts = _re.findall(part_regexp, opt_usage)
- pos_parts = _re.findall(part_regexp, pos_usage)
- assert ' '.join(opt_parts) == opt_usage
- assert ' '.join(pos_parts) == pos_usage
-
- # helper for wrapping lines
- def get_lines(parts, indent, prefix=None):
- lines = []
- line = []
- if prefix is not None:
- line_len = len(prefix) - 1
- else:
- line_len = len(indent) - 1
- for part in parts:
- if line_len + 1 + len(part) > text_width:
- lines.append(indent + ' '.join(line))
- line = []
- line_len = len(indent) - 1
- line.append(part)
- line_len += len(part) + 1
- if line:
- lines.append(indent + ' '.join(line))
- if prefix is not None:
- lines[0] = lines[0][len(indent):]
- return lines
-
- # if prog is short, follow it with optionals or positionals
- if len(prefix) + len(prog) <= 0.75 * text_width:
- indent = ' ' * (len(prefix) + len(prog) + 1)
- if opt_parts:
- lines = get_lines([prog] + opt_parts, indent, prefix)
- lines.extend(get_lines(pos_parts, indent))
- elif pos_parts:
- lines = get_lines([prog] + pos_parts, indent, prefix)
- else:
- lines = [prog]
-
- # if prog is long, put it on its own line
- else:
- indent = ' ' * len(prefix)
- parts = opt_parts + pos_parts
- lines = get_lines(parts, indent)
- if len(lines) > 1:
- lines = []
- lines.extend(get_lines(opt_parts, indent))
- lines.extend(get_lines(pos_parts, indent))
- lines = [prog] + lines
-
- # join lines into usage
- usage = '\n'.join(lines)
-
- # prefix with 'usage:'
- return '%s%s\n\n' % (prefix, usage)
-
- def _format_actions_usage(self, actions, groups):
- # find group indices and identify actions in groups
- group_actions = set()
- inserts = {}
- for group in groups:
- try:
- start = actions.index(group._group_actions[0])
- except ValueError:
- continue
- else:
- end = start + len(group._group_actions)
- if actions[start:end] == group._group_actions:
- for action in group._group_actions:
- group_actions.add(action)
- if not group.required:
- if start in inserts:
- inserts[start] += ' ['
- else:
- inserts[start] = '['
- inserts[end] = ']'
- else:
- if start in inserts:
- inserts[start] += ' ('
- else:
- inserts[start] = '('
- inserts[end] = ')'
- for i in range(start + 1, end):
- inserts[i] = '|'
-
- # collect all actions format strings
- parts = []
- for i, action in enumerate(actions):
-
- # suppressed arguments are marked with None
- # remove | separators for suppressed arguments
- if action.help is SUPPRESS:
- parts.append(None)
- if inserts.get(i) == '|':
- inserts.pop(i)
- elif inserts.get(i + 1) == '|':
- inserts.pop(i + 1)
-
- # produce all arg strings
- elif not action.option_strings:
- part = self._format_args(action, action.dest)
-
- # if it's in a group, strip the outer []
- if action in group_actions:
- if part[0] == '[' and part[-1] == ']':
- part = part[1:-1]
-
- # add the action string to the list
- parts.append(part)
-
- # produce the first way to invoke the option in brackets
- else:
- option_string = action.option_strings[0]
-
- # if the Optional doesn't take a value, format is:
- # -s or --long
- if action.nargs == 0:
- part = '%s' % option_string
-
- # if the Optional takes a value, format is:
- # -s ARGS or --long ARGS
- else:
- default = action.dest.upper()
- args_string = self._format_args(action, default)
- part = '%s %s' % (option_string, args_string)
-
- # make it look optional if it's not required or in a group
- if not action.required and action not in group_actions:
- part = '[%s]' % part
-
- # add the action string to the list
- parts.append(part)
-
- # insert things at the necessary indices
- for i in sorted(inserts, reverse=True):
- parts[i:i] = [inserts[i]]
-
- # join all the action items with spaces
- text = ' '.join([item for item in parts if item is not None])
-
- # clean up separators for mutually exclusive groups
- open = r'[\[(]'
- close = r'[\])]'
- text = _re.sub(r'(%s) ' % open, r'\1', text)
- text = _re.sub(r' (%s)' % close, r'\1', text)
- text = _re.sub(r'%s *%s' % (open, close), r'', text)
- text = _re.sub(r'\(([^|]*)\)', r'\1', text)
- text = text.strip()
-
- # return the text
- return text
-
- def _format_text(self, text):
- if '%(prog)' in text:
- text = text % dict(prog=self._prog)
- text_width = self._width - self._current_indent
- indent = ' ' * self._current_indent
- return self._fill_text(text, text_width, indent) + '\n\n'
-
- def _format_action(self, action):
- # determine the required width and the entry label
- help_position = min(self._action_max_length + 2,
- self._max_help_position)
- help_width = self._width - help_position
- action_width = help_position - self._current_indent - 2
- action_header = self._format_action_invocation(action)
-
- # ho nelp; start on same line and add a final newline
- if not action.help:
- tup = self._current_indent, '', action_header
- action_header = '%*s%s\n' % tup
-
- # short action name; start on the same line and pad two spaces
- elif len(action_header) <= action_width:
- tup = self._current_indent, '', action_width, action_header
- action_header = '%*s%-*s ' % tup
- indent_first = 0
-
- # long action name; start on the next line
- else:
- tup = self._current_indent, '', action_header
- action_header = '%*s%s\n' % tup
- indent_first = help_position
-
- # collect the pieces of the action help
- parts = [action_header]
-
- # if there was help for the action, add lines of help text
- if action.help:
- help_text = self._expand_help(action)
- help_lines = self._split_lines(help_text, help_width)
- parts.append('%*s%s\n' % (indent_first, '', help_lines[0]))
- for line in help_lines[1:]:
- parts.append('%*s%s\n' % (help_position, '', line))
-
- # or add a newline if the description doesn't end with one
- elif not action_header.endswith('\n'):
- parts.append('\n')
-
- # if there are any sub-actions, add their help as well
- for subaction in self._iter_indented_subactions(action):
- parts.append(self._format_action(subaction))
-
- # return a single string
- return self._join_parts(parts)
-
- def _format_action_invocation(self, action):
- if not action.option_strings:
- metavar, = self._metavar_formatter(action, action.dest)(1)
- return metavar
-
- else:
- parts = []
-
- # if the Optional doesn't take a value, format is:
- # -s, --long
- if action.nargs == 0:
- parts.extend(action.option_strings)
-
- # if the Optional takes a value, format is:
- # -s ARGS, --long ARGS
- else:
- default = action.dest.upper()
- args_string = self._format_args(action, default)
- for option_string in action.option_strings:
- parts.append('%s %s' % (option_string, args_string))
-
- return ', '.join(parts)
-
- def _metavar_formatter(self, action, default_metavar):
- if action.metavar is not None:
- result = action.metavar
- elif action.choices is not None:
- choice_strs = [str(choice) for choice in action.choices]
- result = '{%s}' % ','.join(choice_strs)
- else:
- result = default_metavar
-
- def format(tuple_size):
- if isinstance(result, tuple):
- return result
- else:
- return (result, ) * tuple_size
- return format
-
- def _format_args(self, action, default_metavar):
- get_metavar = self._metavar_formatter(action, default_metavar)
- if action.nargs is None:
- result = '%s' % get_metavar(1)
- elif action.nargs == OPTIONAL:
- result = '[%s]' % get_metavar(1)
- elif action.nargs == ZERO_OR_MORE:
- result = '[%s [%s ...]]' % get_metavar(2)
- elif action.nargs == ONE_OR_MORE:
- result = '%s [%s ...]' % get_metavar(2)
- elif action.nargs == REMAINDER:
- result = '...'
- elif action.nargs == PARSER:
- result = '%s ...' % get_metavar(1)
- else:
- formats = ['%s' for _ in range(action.nargs)]
- result = ' '.join(formats) % get_metavar(action.nargs)
- return result
-
- def _expand_help(self, action):
- params = dict(vars(action), prog=self._prog)
- for name in list(params):
- if params[name] is SUPPRESS:
- del params[name]
- for name in list(params):
- if hasattr(params[name], '__name__'):
- params[name] = params[name].__name__
- if params.get('choices') is not None:
- choices_str = ', '.join([str(c) for c in params['choices']])
- params['choices'] = choices_str
- return self._get_help_string(action) % params
-
- def _iter_indented_subactions(self, action):
- try:
- get_subactions = action._get_subactions
- except AttributeError:
- pass
- else:
- self._indent()
- for subaction in get_subactions():
- yield subaction
- self._dedent()
-
- def _split_lines(self, text, width):
- text = self._whitespace_matcher.sub(' ', text).strip()
- return _textwrap.wrap(text, width)
-
- def _fill_text(self, text, width, indent):
- text = self._whitespace_matcher.sub(' ', text).strip()
- return _textwrap.fill(text, width, initial_indent=indent,
- subsequent_indent=indent)
-
- def _get_help_string(self, action):
- return action.help
-
-
-class RawDescriptionHelpFormatter(HelpFormatter):
- """Help message formatter which retains any formatting in descriptions.
-
- Only the name of this class is considered a public API. All the methods
- provided by the class are considered an implementation detail.
- """
-
- def _fill_text(self, text, width, indent):
- return ''.join([indent + line for line in text.splitlines(True)])
-
-
-class RawTextHelpFormatter(RawDescriptionHelpFormatter):
- """Help message formatter which retains formatting of all help text.
-
- Only the name of this class is considered a public API. All the methods
- provided by the class are considered an implementation detail.
- """
-
- def _split_lines(self, text, width):
- return text.splitlines()
-
-
-class ArgumentDefaultsHelpFormatter(HelpFormatter):
- """Help message formatter which adds default values to argument help.
-
- Only the name of this class is considered a public API. All the methods
- provided by the class are considered an implementation detail.
- """
-
- def _get_help_string(self, action):
- help = action.help
- if '%(default)' not in action.help:
- if action.default is not SUPPRESS:
- defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
- if action.option_strings or action.nargs in defaulting_nargs:
- help += ' (default: %(default)s)'
- return help
-
-
-# =====================
-# Options and Arguments
-# =====================
-
-def _get_action_name(argument):
- if argument is None:
- return None
- elif argument.option_strings:
- return '/'.join(argument.option_strings)
- elif argument.metavar not in (None, SUPPRESS):
- return argument.metavar
- elif argument.dest not in (None, SUPPRESS):
- return argument.dest
- else:
- return None
-
-
-class ArgumentError(Exception):
- """An error from creating or using an argument (optional or positional).
-
- The string value of this exception is the message, augmented with
- information about the argument that caused it.
- """
-
- def __init__(self, argument, message):
- self.argument_name = _get_action_name(argument)
- self.message = message
-
- def __str__(self):
- if self.argument_name is None:
- format = '%(message)s'
- else:
- format = 'argument %(argument_name)s: %(message)s'
- return format % dict(message=self.message,
- argument_name=self.argument_name)
-
-
-class ArgumentTypeError(Exception):
- """An error from trying to convert a command line string to a type."""
- pass
-
-
-# ==============
-# Action classes
-# ==============
-
-class Action(_AttributeHolder):
- """Information about how to convert command line strings to Python objects.
-
- Action objects are used by an ArgumentParser to represent the information
- needed to parse a single argument from one or more strings from the
- command line. The keyword arguments to the Action constructor are also
- all attributes of Action instances.
-
- Keyword Arguments:
-
- - option_strings -- A list of command-line option strings which
- should be associated with this action.
-
- - dest -- The name of the attribute to hold the created object(s)
-
- - nargs -- The number of command-line arguments that should be
- consumed. By default, one argument will be consumed and a single
- value will be produced. Other values include:
- - N (an integer) consumes N arguments (and produces a list)
- - '?' consumes zero or one arguments
- - '*' consumes zero or more arguments (and produces a list)
- - '+' consumes one or more arguments (and produces a list)
- Note that the difference between the default and nargs=1 is that
- with the default, a single value will be produced, while with
- nargs=1, a list containing a single value will be produced.
-
- - const -- The value to be produced if the option is specified and the
- option uses an action that takes no values.
-
- - default -- The value to be produced if the option is not specified.
-
- - type -- The type which the command-line arguments should be converted
- to, should be one of 'string', 'int', 'float', 'complex' or a
- callable object that accepts a single string argument. If None,
- 'string' is assumed.
-
- - choices -- A container of values that should be allowed. If not None,
- after a command-line argument has been converted to the appropriate
- type, an exception will be raised if it is not a member of this
- collection.
-
- - required -- True if the action must always be specified at the
- command line. This is only meaningful for optional command-line
- arguments.
-
- - help -- The help string describing the argument.
-
- - metavar -- The name to be used for the option's argument with the
- help string. If None, the 'dest' value will be used as the name.
- """
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=None,
- choices=None,
- required=False,
- help=None,
- metavar=None):
- self.option_strings = option_strings
- self.dest = dest
- self.nargs = nargs
- self.const = const
- self.default = default
- self.type = type
- self.choices = choices
- self.required = required
- self.help = help
- self.metavar = metavar
-
- def _get_kwargs(self):
- names = [
- 'option_strings',
- 'dest',
- 'nargs',
- 'const',
- 'default',
- 'type',
- 'choices',
- 'help',
- 'metavar',
- ]
- return [(name, getattr(self, name)) for name in names]
-
- def __call__(self, parser, namespace, values, option_string=None):
- raise NotImplementedError(_('.__call__() not defined'))
-
-
-class _StoreAction(Action):
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=None,
- choices=None,
- required=False,
- help=None,
- metavar=None):
- if nargs == 0:
- raise ValueError('nargs for store actions must be > 0; if you '
- 'have nothing to store, actions such as store '
- 'true or store const may be more appropriate')
- if const is not None and nargs != OPTIONAL:
- raise ValueError('nargs must be %r to supply const' % OPTIONAL)
- super(_StoreAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=nargs,
- const=const,
- default=default,
- type=type,
- choices=choices,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- setattr(namespace, self.dest, values)
-
-
-class _StoreConstAction(Action):
-
- def __init__(self,
- option_strings,
- dest,
- const,
- default=None,
- required=False,
- help=None,
- metavar=None):
- super(_StoreConstAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=0,
- const=const,
- default=default,
- required=required,
- help=help)
-
- def __call__(self, parser, namespace, values, option_string=None):
- setattr(namespace, self.dest, self.const)
-
-
-class _StoreTrueAction(_StoreConstAction):
-
- def __init__(self,
- option_strings,
- dest,
- default=False,
- required=False,
- help=None):
- super(_StoreTrueAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- const=True,
- default=default,
- required=required,
- help=help)
-
-
-class _StoreFalseAction(_StoreConstAction):
-
- def __init__(self,
- option_strings,
- dest,
- default=True,
- required=False,
- help=None):
- super(_StoreFalseAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- const=False,
- default=default,
- required=required,
- help=help)
-
-
-class _AppendAction(Action):
-
- def __init__(self,
- option_strings,
- dest,
- nargs=None,
- const=None,
- default=None,
- type=None,
- choices=None,
- required=False,
- help=None,
- metavar=None):
- if nargs == 0:
- raise ValueError('nargs for append actions must be > 0; if arg '
- 'strings are not supplying the value to append, '
- 'the append const action may be more appropriate')
- if const is not None and nargs != OPTIONAL:
- raise ValueError('nargs must be %r to supply const' % OPTIONAL)
- super(_AppendAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=nargs,
- const=const,
- default=default,
- type=type,
- choices=choices,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- items = _copy.copy(_ensure_value(namespace, self.dest, []))
- items.append(values)
- setattr(namespace, self.dest, items)
-
-
-class _AppendConstAction(Action):
-
- def __init__(self,
- option_strings,
- dest,
- const,
- default=None,
- required=False,
- help=None,
- metavar=None):
- super(_AppendConstAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=0,
- const=const,
- default=default,
- required=required,
- help=help,
- metavar=metavar)
-
- def __call__(self, parser, namespace, values, option_string=None):
- items = _copy.copy(_ensure_value(namespace, self.dest, []))
- items.append(self.const)
- setattr(namespace, self.dest, items)
-
-
-class _CountAction(Action):
-
- def __init__(self,
- option_strings,
- dest,
- default=None,
- required=False,
- help=None):
- super(_CountAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=0,
- default=default,
- required=required,
- help=help)
-
- def __call__(self, parser, namespace, values, option_string=None):
- new_count = _ensure_value(namespace, self.dest, 0) + 1
- setattr(namespace, self.dest, new_count)
-
-
-class _HelpAction(Action):
-
- def __init__(self,
- option_strings,
- dest=SUPPRESS,
- default=SUPPRESS,
- help=None):
- super(_HelpAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- default=default,
- nargs=0,
- help=help)
-
- def __call__(self, parser, namespace, values, option_string=None):
- parser.print_help()
- parser.exit()
-
-
-class _VersionAction(Action):
-
- def __init__(self,
- option_strings,
- version=None,
- dest=SUPPRESS,
- default=SUPPRESS,
- help="show program's version number and exit"):
- super(_VersionAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- default=default,
- nargs=0,
- help=help)
- self.version = version
-
- def __call__(self, parser, namespace, values, option_string=None):
- version = self.version
- if version is None:
- version = parser.version
- formatter = parser._get_formatter()
- formatter.add_text(version)
- parser.exit(message=formatter.format_help())
-
-
-class _SubParsersAction(Action):
-
- class _ChoicesPseudoAction(Action):
-
- def __init__(self, name, aliases, help):
- metavar = dest = name
- if aliases:
- metavar += ' (%s)' % ', '.join(aliases)
- sup = super(_SubParsersAction._ChoicesPseudoAction, self)
- sup.__init__(option_strings=[], dest=dest, help=help,
- metavar=metavar)
-
- def __init__(self,
- option_strings,
- prog,
- parser_class,
- dest=SUPPRESS,
- help=None,
- metavar=None):
-
- self._prog_prefix = prog
- self._parser_class = parser_class
- self._name_parser_map = {}
- self._choices_actions = []
-
- super(_SubParsersAction, self).__init__(
- option_strings=option_strings,
- dest=dest,
- nargs=PARSER,
- choices=self._name_parser_map,
- help=help,
- metavar=metavar)
-
- def add_parser(self, name, **kwargs):
- # set prog from the existing prefix
- if kwargs.get('prog') is None:
- kwargs['prog'] = '%s %s' % (self._prog_prefix, name)
-
- aliases = kwargs.pop('aliases', ())
-
- # create a pseudo-action to hold the choice help
- if 'help' in kwargs:
- help = kwargs.pop('help')
- choice_action = self._ChoicesPseudoAction(name, aliases, help)
- self._choices_actions.append(choice_action)
-
- # create the parser and add it to the map
- parser = self._parser_class(**kwargs)
- self._name_parser_map[name] = parser
-
- # make parser available under aliases also
- for alias in aliases:
- self._name_parser_map[alias] = parser
-
- return parser
-
- def _get_subactions(self):
- return self._choices_actions
-
- def __call__(self, parser, namespace, values, option_string=None):
- parser_name = values[0]
- arg_strings = values[1:]
-
- # set the parser name if requested
- if self.dest is not SUPPRESS:
- setattr(namespace, self.dest, parser_name)
-
- # select the parser
- try:
- parser = self._name_parser_map[parser_name]
- except KeyError:
- tup = parser_name, ', '.join(self._name_parser_map)
- msg = _('unknown parser %r (choices: %s)' % tup)
- raise ArgumentError(self, msg)
-
- # parse all the remaining options into the namespace
- # store any unrecognized options on the object, so that the top
- # level parser can decide what to do with them
- namespace, arg_strings = parser.parse_known_args(arg_strings, namespace)
- if arg_strings:
- vars(namespace).setdefault(_UNRECOGNIZED_ARGS_ATTR, [])
- getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).extend(arg_strings)
-
-
-# ==============
-# Type classes
-# ==============
-
-class FileType(object):
- """Factory for creating file object types
-
- Instances of FileType are typically passed as type= arguments to the
- ArgumentParser add_argument() method.
-
- Keyword Arguments:
- - mode -- A string indicating how the file is to be opened. Accepts the
- same values as the builtin open() function.
- - bufsize -- The file's desired buffer size. Accepts the same values as
- the builtin open() function.
- """
-
- def __init__(self, mode='r', bufsize=None):
- self._mode = mode
- self._bufsize = bufsize
-
- def __call__(self, string):
- # the special argument "-" means sys.std{in,out}
- if string == '-':
- if 'r' in self._mode:
- return _sys.stdin
- elif 'w' in self._mode:
- return _sys.stdout
- else:
- msg = _('argument "-" with mode %r' % self._mode)
- raise ValueError(msg)
-
- try:
- # all other arguments are used as file names
- if self._bufsize:
- return open(string, self._mode, self._bufsize)
- else:
- return open(string, self._mode)
- except IOError:
- err = _sys.exc_info()[1]
- message = _("can't open '%s': %s")
- raise ArgumentTypeError(message % (string, err))
-
- def __repr__(self):
- args = [self._mode, self._bufsize]
- args_str = ', '.join([repr(arg) for arg in args if arg is not None])
- return '%s(%s)' % (type(self).__name__, args_str)
-
-# ===========================
-# Optional and Positional Parsing
-# ===========================
-
-class Namespace(_AttributeHolder):
- """Simple object for storing attributes.
-
- Implements equality by attribute names and values, and provides a simple
- string representation.
- """
-
- def __init__(self, **kwargs):
- for name in kwargs:
- setattr(self, name, kwargs[name])
-
- __hash__ = None
-
- def __eq__(self, other):
- return vars(self) == vars(other)
-
- def __ne__(self, other):
- return not (self == other)
-
- def __contains__(self, key):
- return key in self.__dict__
-
-
-class _ActionsContainer(object):
-
- def __init__(self,
- description,
- prefix_chars,
- argument_default,
- conflict_handler):
- super(_ActionsContainer, self).__init__()
-
- self.description = description
- self.argument_default = argument_default
- self.prefix_chars = prefix_chars
- self.conflict_handler = conflict_handler
-
- # set up registries
- self._registries = {}
-
- # register actions
- self.register('action', None, _StoreAction)
- self.register('action', 'store', _StoreAction)
- self.register('action', 'store_const', _StoreConstAction)
- self.register('action', 'store_true', _StoreTrueAction)
- self.register('action', 'store_false', _StoreFalseAction)
- self.register('action', 'append', _AppendAction)
- self.register('action', 'append_const', _AppendConstAction)
- self.register('action', 'count', _CountAction)
- self.register('action', 'help', _HelpAction)
- self.register('action', 'version', _VersionAction)
- self.register('action', 'parsers', _SubParsersAction)
-
- # raise an exception if the conflict handler is invalid
- self._get_handler()
-
- # action storage
- self._actions = []
- self._option_string_actions = {}
-
- # groups
- self._action_groups = []
- self._mutually_exclusive_groups = []
-
- # defaults storage
- self._defaults = {}
-
- # determines whether an "option" looks like a negative number
- self._negative_number_matcher = _re.compile(r'^-\d+$|^-\d*\.\d+$')
-
- # whether or not there are any optionals that look like negative
- # numbers -- uses a list so it can be shared and edited
- self._has_negative_number_optionals = []
-
- # ====================
- # Registration methods
- # ====================
- def register(self, registry_name, value, object):
- registry = self._registries.setdefault(registry_name, {})
- registry[value] = object
-
- def _registry_get(self, registry_name, value, default=None):
- return self._registries[registry_name].get(value, default)
-
- # ==================================
- # Namespace default accessor methods
- # ==================================
- def set_defaults(self, **kwargs):
- self._defaults.update(kwargs)
-
- # if these defaults match any existing arguments, replace
- # the previous default on the object with the new one
- for action in self._actions:
- if action.dest in kwargs:
- action.default = kwargs[action.dest]
-
- def get_default(self, dest):
- for action in self._actions:
- if action.dest == dest and action.default is not None:
- return action.default
- return self._defaults.get(dest, None)
-
-
- # =======================
- # Adding argument actions
- # =======================
- def add_argument(self, *args, **kwargs):
- """
- add_argument(dest, ..., name=value, ...)
- add_argument(option_string, option_string, ..., name=value, ...)
- """
-
- # if no positional args are supplied or only one is supplied and
- # it doesn't look like an option string, parse a positional
- # argument
- chars = self.prefix_chars
- if not args or len(args) == 1 and args[0][0] not in chars:
- if args and 'dest' in kwargs:
- raise ValueError('dest supplied twice for positional argument')
- kwargs = self._get_positional_kwargs(*args, **kwargs)
-
- # otherwise, we're adding an optional argument
- else:
- kwargs = self._get_optional_kwargs(*args, **kwargs)
-
- # if no default was supplied, use the parser-level default
- if 'default' not in kwargs:
- dest = kwargs['dest']
- if dest in self._defaults:
- kwargs['default'] = self._defaults[dest]
- elif self.argument_default is not None:
- kwargs['default'] = self.argument_default
-
- # create the action object, and add it to the parser
- action_class = self._pop_action_class(kwargs)
- if not _callable(action_class):
- raise ValueError('unknown action "%s"' % action_class)
- action = action_class(**kwargs)
-
- # raise an error if the action type is not callable
- type_func = self._registry_get('type', action.type, action.type)
- if not _callable(type_func):
- raise ValueError('%r is not callable' % type_func)
-
- return self._add_action(action)
-
- def add_argument_group(self, *args, **kwargs):
- group = _ArgumentGroup(self, *args, **kwargs)
- self._action_groups.append(group)
- return group
-
- def add_mutually_exclusive_group(self, **kwargs):
- group = _MutuallyExclusiveGroup(self, **kwargs)
- self._mutually_exclusive_groups.append(group)
- return group
-
- def _add_action(self, action):
- # resolve any conflicts
- self._check_conflict(action)
-
- # add to actions list
- self._actions.append(action)
- action.container = self
-
- # index the action by any option strings it has
- for option_string in action.option_strings:
- self._option_string_actions[option_string] = action
-
- # set the flag if any option strings look like negative numbers
- for option_string in action.option_strings:
- if self._negative_number_matcher.match(option_string):
- if not self._has_negative_number_optionals:
- self._has_negative_number_optionals.append(True)
-
- # return the created action
- return action
-
- def _remove_action(self, action):
- self._actions.remove(action)
-
- def _add_container_actions(self, container):
- # collect groups by titles
- title_group_map = {}
- for group in self._action_groups:
- if group.title in title_group_map:
- msg = _('cannot merge actions - two groups are named %r')
- raise ValueError(msg % (group.title))
- title_group_map[group.title] = group
-
- # map each action to its group
- group_map = {}
- for group in container._action_groups:
-
- # if a group with the title exists, use that, otherwise
- # create a new group matching the container's group
- if group.title not in title_group_map:
- title_group_map[group.title] = self.add_argument_group(
- title=group.title,
- description=group.description,
- conflict_handler=group.conflict_handler)
-
- # map the actions to their new group
- for action in group._group_actions:
- group_map[action] = title_group_map[group.title]
-
- # add container's mutually exclusive groups
- # NOTE: if add_mutually_exclusive_group ever gains title= and
- # description= then this code will need to be expanded as above
- for group in container._mutually_exclusive_groups:
- mutex_group = self.add_mutually_exclusive_group(
- required=group.required)
-
- # map the actions to their new mutex group
- for action in group._group_actions:
- group_map[action] = mutex_group
-
- # add all actions to this container or their group
- for action in container._actions:
- group_map.get(action, self)._add_action(action)
-
- def _get_positional_kwargs(self, dest, **kwargs):
- # make sure required is not specified
- if 'required' in kwargs:
- msg = _("'required' is an invalid argument for positionals")
- raise TypeError(msg)
-
- # mark positional arguments as required if at least one is
- # always required
- if kwargs.get('nargs') not in [OPTIONAL, ZERO_OR_MORE]:
- kwargs['required'] = True
- if kwargs.get('nargs') == ZERO_OR_MORE and 'default' not in kwargs:
- kwargs['required'] = True
-
- # return the keyword arguments with no option strings
- return dict(kwargs, dest=dest, option_strings=[])
-
- def _get_optional_kwargs(self, *args, **kwargs):
- # determine short and long option strings
- option_strings = []
- long_option_strings = []
- for option_string in args:
- # error on strings that don't start with an appropriate prefix
- if not option_string[0] in self.prefix_chars:
- msg = _('invalid option string %r: '
- 'must start with a character %r')
- tup = option_string, self.prefix_chars
- raise ValueError(msg % tup)
-
- # strings starting with two prefix characters are long options
- option_strings.append(option_string)
- if option_string[0] in self.prefix_chars:
- if len(option_string) > 1:
- if option_string[1] in self.prefix_chars:
- long_option_strings.append(option_string)
-
- # infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
- dest = kwargs.pop('dest', None)
- if dest is None:
- if long_option_strings:
- dest_option_string = long_option_strings[0]
- else:
- dest_option_string = option_strings[0]
- dest = dest_option_string.lstrip(self.prefix_chars)
- if not dest:
- msg = _('dest= is required for options like %r')
- raise ValueError(msg % option_string)
- dest = dest.replace('-', '_')
-
- # return the updated keyword arguments
- return dict(kwargs, dest=dest, option_strings=option_strings)
-
- def _pop_action_class(self, kwargs, default=None):
- action = kwargs.pop('action', default)
- return self._registry_get('action', action, action)
-
- def _get_handler(self):
- # determine function from conflict handler string
- handler_func_name = '_handle_conflict_%s' % self.conflict_handler
- try:
- return getattr(self, handler_func_name)
- except AttributeError:
- msg = _('invalid conflict_resolution value: %r')
- raise ValueError(msg % self.conflict_handler)
-
- def _check_conflict(self, action):
-
- # find all options that conflict with this option
- confl_optionals = []
- for option_string in action.option_strings:
- if option_string in self._option_string_actions:
- confl_optional = self._option_string_actions[option_string]
- confl_optionals.append((option_string, confl_optional))
-
- # resolve any conflicts
- if confl_optionals:
- conflict_handler = self._get_handler()
- conflict_handler(action, confl_optionals)
-
- def _handle_conflict_error(self, action, conflicting_actions):
- message = _('conflicting option string(s): %s')
- conflict_string = ', '.join([option_string
- for option_string, action
- in conflicting_actions])
- raise ArgumentError(action, message % conflict_string)
-
- def _handle_conflict_resolve(self, action, conflicting_actions):
-
- # remove all conflicting options
- for option_string, action in conflicting_actions:
-
- # remove the conflicting option
- action.option_strings.remove(option_string)
- self._option_string_actions.pop(option_string, None)
-
- # if the option now has no option string, remove it from the
- # container holding it
- if not action.option_strings:
- action.container._remove_action(action)
-
-
-class _ArgumentGroup(_ActionsContainer):
-
- def __init__(self, container, title=None, description=None, **kwargs):
- # add any missing keyword arguments by checking the container
- update = kwargs.setdefault
- update('conflict_handler', container.conflict_handler)
- update('prefix_chars', container.prefix_chars)
- update('argument_default', container.argument_default)
- super_init = super(_ArgumentGroup, self).__init__
- super_init(description=description, **kwargs)
-
- # group attributes
- self.title = title
- self._group_actions = []
-
- # share most attributes with the container
- self._registries = container._registries
- self._actions = container._actions
- self._option_string_actions = container._option_string_actions
- self._defaults = container._defaults
- self._has_negative_number_optionals = \
- container._has_negative_number_optionals
-
- def _add_action(self, action):
- action = super(_ArgumentGroup, self)._add_action(action)
- self._group_actions.append(action)
- return action
-
- def _remove_action(self, action):
- super(_ArgumentGroup, self)._remove_action(action)
- self._group_actions.remove(action)
-
-
-class _MutuallyExclusiveGroup(_ArgumentGroup):
-
- def __init__(self, container, required=False):
- super(_MutuallyExclusiveGroup, self).__init__(container)
- self.required = required
- self._container = container
-
- def _add_action(self, action):
- if action.required:
- msg = _('mutually exclusive arguments must be optional')
- raise ValueError(msg)
- action = self._container._add_action(action)
- self._group_actions.append(action)
- return action
-
- def _remove_action(self, action):
- self._container._remove_action(action)
- self._group_actions.remove(action)
-
-
-class ArgumentParser(_AttributeHolder, _ActionsContainer):
- """Object for parsing command line strings into Python objects.
-
- Keyword Arguments:
- - prog -- The name of the program (default: sys.argv[0])
- - usage -- A usage message (default: auto-generated from arguments)
- - description -- A description of what the program does
- - epilog -- Text following the argument descriptions
- - parents -- Parsers whose arguments should be copied into this one
- - formatter_class -- HelpFormatter class for printing help messages
- - prefix_chars -- Characters that prefix optional arguments
- - fromfile_prefix_chars -- Characters that prefix files containing
- additional arguments
- - argument_default -- The default value for all arguments
- - conflict_handler -- String indicating how to handle conflicts
- - add_help -- Add a -h/-help option
- """
-
- def __init__(self,
- prog=None,
- usage=None,
- description=None,
- epilog=None,
- version=None,
- parents=[],
- formatter_class=HelpFormatter,
- prefix_chars='-',
- fromfile_prefix_chars=None,
- argument_default=None,
- conflict_handler='error',
- add_help=True):
-
- if version is not None:
- import warnings
- warnings.warn(
- """The "version" argument to ArgumentParser is deprecated. """
- """Please use """
- """"add_argument(..., action='version', version="N", ...)" """
- """instead""", DeprecationWarning)
-
- superinit = super(ArgumentParser, self).__init__
- superinit(description=description,
- prefix_chars=prefix_chars,
- argument_default=argument_default,
- conflict_handler=conflict_handler)
-
- # default setting for prog
- if prog is None:
- prog = _os.path.basename(_sys.argv[0])
-
- self.prog = prog
- self.usage = usage
- self.epilog = epilog
- self.version = version
- self.formatter_class = formatter_class
- self.fromfile_prefix_chars = fromfile_prefix_chars
- self.add_help = add_help
-
- add_group = self.add_argument_group
- self._positionals = add_group(_('positional arguments'))
- self._optionals = add_group(_('optional arguments'))
- self._subparsers = None
-
- # register types
- def identity(string):
- return string
- self.register('type', None, identity)
-
- # add help and version arguments if necessary
- # (using explicit default to override global argument_default)
- if '-' in prefix_chars:
- default_prefix = '-'
- else:
- default_prefix = prefix_chars[0]
- if self.add_help:
- self.add_argument(
- default_prefix+'h', default_prefix*2+'help',
- action='help', default=SUPPRESS,
- help=_('show this help message and exit'))
- if self.version:
- self.add_argument(
- default_prefix+'v', default_prefix*2+'version',
- action='version', default=SUPPRESS,
- version=self.version,
- help=_("show program's version number and exit"))
-
- # add parent arguments and defaults
- for parent in parents:
- self._add_container_actions(parent)
- try:
- defaults = parent._defaults
- except AttributeError:
- pass
- else:
- self._defaults.update(defaults)
-
- # =======================
- # Pretty __repr__ methods
- # =======================
- def _get_kwargs(self):
- names = [
- 'prog',
- 'usage',
- 'description',
- 'version',
- 'formatter_class',
- 'conflict_handler',
- 'add_help',
- ]
- return [(name, getattr(self, name)) for name in names]
-
- # ==================================
- # Optional/Positional adding methods
- # ==================================
- def add_subparsers(self, **kwargs):
- if self._subparsers is not None:
- self.error(_('cannot have multiple subparser arguments'))
-
- # add the parser class to the arguments if it's not present
- kwargs.setdefault('parser_class', type(self))
-
- if 'title' in kwargs or 'description' in kwargs:
- title = _(kwargs.pop('title', 'subcommands'))
- description = _(kwargs.pop('description', None))
- self._subparsers = self.add_argument_group(title, description)
- else:
- self._subparsers = self._positionals
-
- # prog defaults to the usage message of this parser, skipping
- # optional arguments and with no "usage:" prefix
- if kwargs.get('prog') is None:
- formatter = self._get_formatter()
- positionals = self._get_positional_actions()
- groups = self._mutually_exclusive_groups
- formatter.add_usage(self.usage, positionals, groups, '')
- kwargs['prog'] = formatter.format_help().strip()
-
- # create the parsers action and add it to the positionals list
- parsers_class = self._pop_action_class(kwargs, 'parsers')
- action = parsers_class(option_strings=[], **kwargs)
- self._subparsers._add_action(action)
-
- # return the created parsers action
- return action
-
- def _add_action(self, action):
- if action.option_strings:
- self._optionals._add_action(action)
- else:
- self._positionals._add_action(action)
- return action
-
- def _get_optional_actions(self):
- return [action
- for action in self._actions
- if action.option_strings]
-
- def _get_positional_actions(self):
- return [action
- for action in self._actions
- if not action.option_strings]
-
- # =====================================
- # Command line argument parsing methods
- # =====================================
- def parse_args(self, args=None, namespace=None):
- args, argv = self.parse_known_args(args, namespace)
- if argv:
- msg = _('unrecognized arguments: %s')
- self.error(msg % ' '.join(argv))
- return args
-
- def parse_known_args(self, args=None, namespace=None):
- # args default to the system args
- if args is None:
- args = _sys.argv[1:]
-
- # default Namespace built from parser defaults
- if namespace is None:
- namespace = Namespace()
-
- # add any action defaults that aren't present
- for action in self._actions:
- if action.dest is not SUPPRESS:
- if not hasattr(namespace, action.dest):
- if action.default is not SUPPRESS:
- setattr(namespace, action.dest, action.default)
-
- # add any parser defaults that aren't present
- for dest in self._defaults:
- if not hasattr(namespace, dest):
- setattr(namespace, dest, self._defaults[dest])
-
- # parse the arguments and exit if there are any errors
- try:
- namespace, args = self._parse_known_args(args, namespace)
- if hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR):
- args.extend(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))
- delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
- return namespace, args
- except ArgumentError:
- err = _sys.exc_info()[1]
- self.error(str(err))
-
- def _parse_known_args(self, arg_strings, namespace):
- # replace arg strings that are file references
- if self.fromfile_prefix_chars is not None:
- arg_strings = self._read_args_from_files(arg_strings)
-
- # map all mutually exclusive arguments to the other arguments
- # they can't occur with
- action_conflicts = {}
- for mutex_group in self._mutually_exclusive_groups:
- group_actions = mutex_group._group_actions
- for i, mutex_action in enumerate(mutex_group._group_actions):
- conflicts = action_conflicts.setdefault(mutex_action, [])
- conflicts.extend(group_actions[:i])
- conflicts.extend(group_actions[i + 1:])
-
- # find all option indices, and determine the arg_string_pattern
- # which has an 'O' if there is an option at an index,
- # an 'A' if there is an argument, or a '-' if there is a '--'
- option_string_indices = {}
- arg_string_pattern_parts = []
- arg_strings_iter = iter(arg_strings)
- for i, arg_string in enumerate(arg_strings_iter):
-
- # all args after -- are non-options
- if arg_string == '--':
- arg_string_pattern_parts.append('-')
- for arg_string in arg_strings_iter:
- arg_string_pattern_parts.append('A')
-
- # otherwise, add the arg to the arg strings
- # and note the index if it was an option
- else:
- option_tuple = self._parse_optional(arg_string)
- if option_tuple is None:
- pattern = 'A'
- else:
- option_string_indices[i] = option_tuple
- pattern = 'O'
- arg_string_pattern_parts.append(pattern)
-
- # join the pieces together to form the pattern
- arg_strings_pattern = ''.join(arg_string_pattern_parts)
-
- # converts arg strings to the appropriate and then takes the action
- seen_actions = set()
- seen_non_default_actions = set()
-
- def take_action(action, argument_strings, option_string=None):
- seen_actions.add(action)
- argument_values = self._get_values(action, argument_strings)
-
- # error if this argument is not allowed with other previously
- # seen arguments, assuming that actions that use the default
- # value don't really count as "present"
- if argument_values is not action.default:
- seen_non_default_actions.add(action)
- for conflict_action in action_conflicts.get(action, []):
- if conflict_action in seen_non_default_actions:
- msg = _('not allowed with argument %s')
- action_name = _get_action_name(conflict_action)
- raise ArgumentError(action, msg % action_name)
-
- # take the action if we didn't receive a SUPPRESS value
- # (e.g. from a default)
- if argument_values is not SUPPRESS:
- action(self, namespace, argument_values, option_string)
-
- # function to convert arg_strings into an optional action
- def consume_optional(start_index):
-
- # get the optional identified at this index
- option_tuple = option_string_indices[start_index]
- action, option_string, explicit_arg = option_tuple
-
- # identify additional optionals in the same arg string
- # (e.g. -xyz is the same as -x -y -z if no args are required)
- match_argument = self._match_argument
- action_tuples = []
- while True:
-
- # if we found no optional action, skip it
- if action is None:
- extras.append(arg_strings[start_index])
- return start_index + 1
-
- # if there is an explicit argument, try to match the
- # optional's string arguments to only this
- if explicit_arg is not None:
- arg_count = match_argument(action, 'A')
-
- # if the action is a single-dash option and takes no
- # arguments, try to parse more single-dash options out
- # of the tail of the option string
- chars = self.prefix_chars
- if arg_count == 0 and option_string[1] not in chars:
- action_tuples.append((action, [], option_string))
- char = option_string[0]
- option_string = char + explicit_arg[0]
- new_explicit_arg = explicit_arg[1:] or None
- optionals_map = self._option_string_actions
- if option_string in optionals_map:
- action = optionals_map[option_string]
- explicit_arg = new_explicit_arg
- else:
- msg = _('ignored explicit argument %r')
- raise ArgumentError(action, msg % explicit_arg)
-
- # if the action expect exactly one argument, we've
- # successfully matched the option; exit the loop
- elif arg_count == 1:
- stop = start_index + 1
- args = [explicit_arg]
- action_tuples.append((action, args, option_string))
- break
-
- # error if a double-dash option did not use the
- # explicit argument
- else:
- msg = _('ignored explicit argument %r')
- raise ArgumentError(action, msg % explicit_arg)
-
- # if there is no explicit argument, try to match the
- # optional's string arguments with the following strings
- # if successful, exit the loop
- else:
- start = start_index + 1
- selected_patterns = arg_strings_pattern[start:]
- arg_count = match_argument(action, selected_patterns)
- stop = start + arg_count
- args = arg_strings[start:stop]
- action_tuples.append((action, args, option_string))
- break
-
- # add the Optional to the list and return the index at which
- # the Optional's string args stopped
- assert action_tuples
- for action, args, option_string in action_tuples:
- take_action(action, args, option_string)
- return stop
-
- # the list of Positionals left to be parsed; this is modified
- # by consume_positionals()
- positionals = self._get_positional_actions()
-
- # function to convert arg_strings into positional actions
- def consume_positionals(start_index):
- # match as many Positionals as possible
- match_partial = self._match_arguments_partial
- selected_pattern = arg_strings_pattern[start_index:]
- arg_counts = match_partial(positionals, selected_pattern)
-
- # slice off the appropriate arg strings for each Positional
- # and add the Positional and its args to the list
- for action, arg_count in zip(positionals, arg_counts):
- args = arg_strings[start_index: start_index + arg_count]
- start_index += arg_count
- take_action(action, args)
-
- # slice off the Positionals that we just parsed and return the
- # index at which the Positionals' string args stopped
- positionals[:] = positionals[len(arg_counts):]
- return start_index
-
- # consume Positionals and Optionals alternately, until we have
- # passed the last option string
- extras = []
- start_index = 0
- if option_string_indices:
- max_option_string_index = max(option_string_indices)
- else:
- max_option_string_index = -1
- while start_index <= max_option_string_index:
-
- # consume any Positionals preceding the next option
- next_option_string_index = min([
- index
- for index in option_string_indices
- if index >= start_index])
- if start_index != next_option_string_index:
- positionals_end_index = consume_positionals(start_index)
-
- # only try to parse the next optional if we didn't consume
- # the option string during the positionals parsing
- if positionals_end_index > start_index:
- start_index = positionals_end_index
- continue
- else:
- start_index = positionals_end_index
-
- # if we consumed all the positionals we could and we're not
- # at the index of an option string, there were extra arguments
- if start_index not in option_string_indices:
- strings = arg_strings[start_index:next_option_string_index]
- extras.extend(strings)
- start_index = next_option_string_index
-
- # consume the next optional and any arguments for it
- start_index = consume_optional(start_index)
-
- # consume any positionals following the last Optional
- stop_index = consume_positionals(start_index)
-
- # if we didn't consume all the argument strings, there were extras
- extras.extend(arg_strings[stop_index:])
-
- # if we didn't use all the Positional objects, there were too few
- # arg strings supplied.
- if positionals:
- self.error(_('too few arguments'))
-
- # make sure all required actions were present, and convert defaults.
- for action in self._actions:
- if action not in seen_actions:
- if action.required:
- name = _get_action_name(action)
- self.error(_('argument %s is required') % name)
- else:
- # Convert action default now instead of doing it before
- # parsing arguments to avoid calling convert functions
- # twice (which may fail) if the argument was given, but
- # only if it was defined already in the namespace
- if (action.default is not None and
- isinstance(action.default, basestring) and
- hasattr(namespace, action.dest) and
- action.default is getattr(namespace, action.dest)):
- setattr(namespace, action.dest,
- self._get_value(action, action.default))
-
- # make sure all required groups had one option present
- for group in self._mutually_exclusive_groups:
- if group.required:
- for action in group._group_actions:
- if action in seen_non_default_actions:
- break
-
- # if no actions were used, report the error
- else:
- names = [_get_action_name(action)
- for action in group._group_actions
- if action.help is not SUPPRESS]
- msg = _('one of the arguments %s is required')
- self.error(msg % ' '.join(names))
-
- # return the updated namespace and the extra arguments
- return namespace, extras
-
- def _read_args_from_files(self, arg_strings):
- # expand arguments referencing files
- new_arg_strings = []
- for arg_string in arg_strings:
-
- # for regular arguments, just add them back into the list
- if arg_string[0] not in self.fromfile_prefix_chars:
- new_arg_strings.append(arg_string)
-
- # replace arguments referencing files with the file content
- else:
- try:
- args_file = open(arg_string[1:])
- try:
- arg_strings = []
- for arg_line in args_file.read().splitlines():
- for arg in self.convert_arg_line_to_args(arg_line):
- arg_strings.append(arg)
- arg_strings = self._read_args_from_files(arg_strings)
- new_arg_strings.extend(arg_strings)
- finally:
- args_file.close()
- except IOError:
- err = _sys.exc_info()[1]
- self.error(str(err))
-
- # return the modified argument list
- return new_arg_strings
-
- def convert_arg_line_to_args(self, arg_line):
- return [arg_line]
-
- def _match_argument(self, action, arg_strings_pattern):
- # match the pattern for this action to the arg strings
- nargs_pattern = self._get_nargs_pattern(action)
- match = _re.match(nargs_pattern, arg_strings_pattern)
-
- # raise an exception if we weren't able to find a match
- if match is None:
- nargs_errors = {
- None: _('expected one argument'),
- OPTIONAL: _('expected at most one argument'),
- ONE_OR_MORE: _('expected at least one argument'),
- }
- default = _('expected %s argument(s)') % action.nargs
- msg = nargs_errors.get(action.nargs, default)
- raise ArgumentError(action, msg)
-
- # return the number of arguments matched
- return len(match.group(1))
-
- def _match_arguments_partial(self, actions, arg_strings_pattern):
- # progressively shorten the actions list by slicing off the
- # final actions until we find a match
- result = []
- for i in range(len(actions), 0, -1):
- actions_slice = actions[:i]
- pattern = ''.join([self._get_nargs_pattern(action)
- for action in actions_slice])
- match = _re.match(pattern, arg_strings_pattern)
- if match is not None:
- result.extend([len(string) for string in match.groups()])
- break
-
- # return the list of arg string counts
- return result
-
- def _parse_optional(self, arg_string):
- # if it's an empty string, it was meant to be a positional
- if not arg_string:
- return None
-
- # if it doesn't start with a prefix, it was meant to be positional
- if not arg_string[0] in self.prefix_chars:
- return None
-
- # if the option string is present in the parser, return the action
- if arg_string in self._option_string_actions:
- action = self._option_string_actions[arg_string]
- return action, arg_string, None
-
- # if it's just a single character, it was meant to be positional
- if len(arg_string) == 1:
- return None
-
- # if the option string before the "=" is present, return the action
- if '=' in arg_string:
- option_string, explicit_arg = arg_string.split('=', 1)
- if option_string in self._option_string_actions:
- action = self._option_string_actions[option_string]
- return action, option_string, explicit_arg
-
- # search through all possible prefixes of the option string
- # and all actions in the parser for possible interpretations
- option_tuples = self._get_option_tuples(arg_string)
-
- # if multiple actions match, the option string was ambiguous
- if len(option_tuples) > 1:
- options = ', '.join([option_string
- for action, option_string, explicit_arg in option_tuples])
- tup = arg_string, options
- self.error(_('ambiguous option: %s could match %s') % tup)
-
- # if exactly one action matched, this segmentation is good,
- # so return the parsed action
- elif len(option_tuples) == 1:
- option_tuple, = option_tuples
- return option_tuple
-
- # if it was not found as an option, but it looks like a negative
- # number, it was meant to be positional
- # unless there are negative-number-like options
- if self._negative_number_matcher.match(arg_string):
- if not self._has_negative_number_optionals:
- return None
-
- # if it contains a space, it was meant to be a positional
- if ' ' in arg_string:
- return None
-
- # it was meant to be an optional but there is no such option
- # in this parser (though it might be a valid option in a subparser)
- return None, arg_string, None
-
- def _get_option_tuples(self, option_string):
- result = []
-
- # option strings starting with two prefix characters are only
- # split at the '='
- chars = self.prefix_chars
- if option_string[0] in chars and option_string[1] in chars:
- if '=' in option_string:
- option_prefix, explicit_arg = option_string.split('=', 1)
- else:
- option_prefix = option_string
- explicit_arg = None
- for option_string in self._option_string_actions:
- if option_string.startswith(option_prefix):
- action = self._option_string_actions[option_string]
- tup = action, option_string, explicit_arg
- result.append(tup)
-
- # single character options can be concatenated with their arguments
- # but multiple character options always have to have their argument
- # separate
- elif option_string[0] in chars and option_string[1] not in chars:
- option_prefix = option_string
- explicit_arg = None
- short_option_prefix = option_string[:2]
- short_explicit_arg = option_string[2:]
-
- for option_string in self._option_string_actions:
- if option_string == short_option_prefix:
- action = self._option_string_actions[option_string]
- tup = action, option_string, short_explicit_arg
- result.append(tup)
- elif option_string.startswith(option_prefix):
- action = self._option_string_actions[option_string]
- tup = action, option_string, explicit_arg
- result.append(tup)
-
- # shouldn't ever get here
- else:
- self.error(_('unexpected option string: %s') % option_string)
-
- # return the collected option tuples
- return result
-
- def _get_nargs_pattern(self, action):
- # in all examples below, we have to allow for '--' args
- # which are represented as '-' in the pattern
- nargs = action.nargs
-
- # the default (None) is assumed to be a single argument
- if nargs is None:
- nargs_pattern = '(-*A-*)'
-
- # allow zero or one arguments
- elif nargs == OPTIONAL:
- nargs_pattern = '(-*A?-*)'
-
- # allow zero or more arguments
- elif nargs == ZERO_OR_MORE:
- nargs_pattern = '(-*[A-]*)'
-
- # allow one or more arguments
- elif nargs == ONE_OR_MORE:
- nargs_pattern = '(-*A[A-]*)'
-
- # allow any number of options or arguments
- elif nargs == REMAINDER:
- nargs_pattern = '([-AO]*)'
-
- # allow one argument followed by any number of options or arguments
- elif nargs == PARSER:
- nargs_pattern = '(-*A[-AO]*)'
-
- # all others should be integers
- else:
- nargs_pattern = '(-*%s-*)' % '-*'.join('A' * nargs)
-
- # if this is an optional action, -- is not allowed
- if action.option_strings:
- nargs_pattern = nargs_pattern.replace('-*', '')
- nargs_pattern = nargs_pattern.replace('-', '')
-
- # return the pattern
- return nargs_pattern
-
- # ========================
- # Value conversion methods
- # ========================
- def _get_values(self, action, arg_strings):
- # for everything but PARSER args, strip out '--'
- if action.nargs not in [PARSER, REMAINDER]:
- arg_strings = [s for s in arg_strings if s != '--']
-
- # optional argument produces a default when not present
- if not arg_strings and action.nargs == OPTIONAL:
- if action.option_strings:
- value = action.const
- else:
- value = action.default
- if isinstance(value, basestring):
- value = self._get_value(action, value)
- self._check_value(action, value)
-
- # when nargs='*' on a positional, if there were no command-line
- # args, use the default if it is anything other than None
- elif (not arg_strings and action.nargs == ZERO_OR_MORE and
- not action.option_strings):
- if action.default is not None:
- value = action.default
- else:
- value = arg_strings
- self._check_value(action, value)
-
- # single argument or optional argument produces a single value
- elif len(arg_strings) == 1 and action.nargs in [None, OPTIONAL]:
- arg_string, = arg_strings
- value = self._get_value(action, arg_string)
- self._check_value(action, value)
-
- # REMAINDER arguments convert all values, checking none
- elif action.nargs == REMAINDER:
- value = [self._get_value(action, v) for v in arg_strings]
-
- # PARSER arguments convert all values, but check only the first
- elif action.nargs == PARSER:
- value = [self._get_value(action, v) for v in arg_strings]
- self._check_value(action, value[0])
-
- # all other types of nargs produce a list
- else:
- value = [self._get_value(action, v) for v in arg_strings]
- for v in value:
- self._check_value(action, v)
-
- # return the converted value
- return value
-
- def _get_value(self, action, arg_string):
- type_func = self._registry_get('type', action.type, action.type)
- if not _callable(type_func):
- msg = _('%r is not callable')
- raise ArgumentError(action, msg % type_func)
-
- # convert the value to the appropriate type
- try:
- result = type_func(arg_string)
-
- # ArgumentTypeErrors indicate errors
- except ArgumentTypeError:
- name = getattr(action.type, '__name__', repr(action.type))
- msg = str(_sys.exc_info()[1])
- raise ArgumentError(action, msg)
-
- # TypeErrors or ValueErrors also indicate errors
- except (TypeError, ValueError):
- name = getattr(action.type, '__name__', repr(action.type))
- msg = _('invalid %s value: %r')
- raise ArgumentError(action, msg % (name, arg_string))
-
- # return the converted value
- return result
-
- def _check_value(self, action, value):
- # converted value must be one of the choices (if specified)
- if action.choices is not None and value not in action.choices:
- tup = value, ', '.join(map(repr, action.choices))
- msg = _('invalid choice: %r (choose from %s)') % tup
- raise ArgumentError(action, msg)
-
- # =======================
- # Help-formatting methods
- # =======================
- def format_usage(self):
- formatter = self._get_formatter()
- formatter.add_usage(self.usage, self._actions,
- self._mutually_exclusive_groups)
- return formatter.format_help()
-
- def format_help(self):
- formatter = self._get_formatter()
-
- # usage
- formatter.add_usage(self.usage, self._actions,
- self._mutually_exclusive_groups)
-
- # description
- formatter.add_text(self.description)
-
- # positionals, optionals and user-defined groups
- for action_group in self._action_groups:
- formatter.start_section(action_group.title)
- formatter.add_text(action_group.description)
- formatter.add_arguments(action_group._group_actions)
- formatter.end_section()
-
- # epilog
- formatter.add_text(self.epilog)
-
- # determine help from format above
- return formatter.format_help()
-
- def format_version(self):
- import warnings
- warnings.warn(
- 'The format_version method is deprecated -- the "version" '
- 'argument to ArgumentParser is no longer supported.',
- DeprecationWarning)
- formatter = self._get_formatter()
- formatter.add_text(self.version)
- return formatter.format_help()
-
- def _get_formatter(self):
- return self.formatter_class(prog=self.prog)
-
- # =====================
- # Help-printing methods
- # =====================
- def print_usage(self, file=None):
- if file is None:
- file = _sys.stdout
- self._print_message(self.format_usage(), file)
-
- def print_help(self, file=None):
- if file is None:
- file = _sys.stdout
- self._print_message(self.format_help(), file)
-
- def print_version(self, file=None):
- import warnings
- warnings.warn(
- 'The print_version method is deprecated -- the "version" '
- 'argument to ArgumentParser is no longer supported.',
- DeprecationWarning)
- self._print_message(self.format_version(), file)
-
- def _print_message(self, message, file=None):
- if message:
- if file is None:
- file = _sys.stderr
- file.write(message)
-
- # ===============
- # Exiting methods
- # ===============
- def exit(self, status=0, message=None):
- if message:
- self._print_message(message, _sys.stderr)
- _sys.exit(status)
-
- def error(self, message):
- """error(message: string)
-
- Prints a usage message incorporating the message to stderr and
- exits.
-
- If you override this in a subclass, it should not return -- it
- should either exit or raise an exception.
- """
- self.print_usage(_sys.stderr)
- self.exit(2, _('%s: error: %s\n') % (self.prog, message))
diff --git a/keycodemapdb/tools/keymap-gen b/keycodemapdb/tools/keymap-gen
deleted file mode 100755
index 22b4f71..0000000
--- a/keycodemapdb/tools/keymap-gen
+++ /dev/null
@@ -1,1147 +0,0 @@
-#!/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):
- self._boilerplate([
- "This file is auto-generated from keymaps.csv",
- "Database checksum sha256(%s)" % database.mapchecksum,
- "To re-generate, run:",
- " %s" % args,
- ])
-
-class LanguageSrcGenerator(LanguageGenerator):
-
- TYPE_INT = "integer"
- TYPE_STRING = "string"
- TYPE_ENUM = "enum"
-
- def _array_start(self, varname, length, defvalue, fromtype, totype):
- raise NotImplementedError()
-
- def _array_end(self, fromtype, totype):
- raise NotImplementedError()
-
- def _array_entry(self, index, value, comment, fromtype, totype):
- raise NotImplementedError()
-
- def generate_code_map(self, varname, database, frommapname, tomapname):
- if frommapname not in database.mapfrom:
- raise Exception("Unknown map %s, expected one of %s" % (
- frommapname, ", ".join(database.mapfrom.keys())))
- if tomapname not in database.mapto:
- raise Exception("Unknown map %s, expected one of %s" % (
- tomapname, ", ".join(database.mapto.keys())))
-
- tolinux = database.mapfrom[frommapname]
- fromlinux = database.mapto[tomapname]
-
- if varname is None:
- varname = "code_map_%s_to_%s" % (frommapname, tomapname)
-
- if frommapname in database.ENUM_COLUMNS:
- fromtype = self.TYPE_ENUM
- elif type(list(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(list(fromlinux.values())[0]) == str:
- totype = self.TYPE_STRING
- else:
- totype = self.TYPE_INT
-
- keys = list(tolinux.keys())
- keys.sort()
- if fromtype == self.TYPE_INT:
- keys = range(keys[-1] + 1)
-
- if fromtype == self.TYPE_ENUM:
- keymax = database.ENUM_BOUND[frommapname]
- else:
- keymax = len(keys)
-
- defvalue = fromlinux.get(0, None)
- if fromtype == self.TYPE_ENUM:
- self._array_start(varname, keymax, defvalue, fromtype, totype)
- else:
- self._array_start(varname, keymax, None, fromtype, totype)
-
- for src in keys:
- linux = tolinux.get(src, None)
- if linux is None:
- dst = None
- else:
- dst = fromlinux.get(linux, defvalue)
-
- comment = "%s -> %s -> %s" % (self._label(database, frommapname, src, linux),
- self._label(database, Database.MAP_LINUX, linux, linux),
- self._label(database, tomapname, dst, linux))
- self._array_entry(src, dst, comment, fromtype, totype)
- self._array_end(fromtype, totype)
-
- def generate_code_table(self, varname, database, mapname):
- if mapname not in database.mapto:
- raise Exception("Unknown map %s, expected one of %s" % (
- mapname, ", ".join(database.mapto.keys())))
-
- keys = list(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(list(database.mapto[mapname].values())[0]) == str:
- totype = self.TYPE_STRING
- else:
- totype = self.TYPE_INT
-
- self._array_start(varname, len(keys), None, self.TYPE_INT, totype)
-
- defvalue = database.mapto[mapname].get(0, None)
- for i in range(len(keys)):
- key = keys[i]
- dst = database.mapto[mapname].get(key, defvalue)
- self._array_entry(i, dst, names[i], self.TYPE_INT, totype)
-
- self._array_end(self.TYPE_INT, totype)
-
- def generate_name_map(self, varname, database, frommapname, tomapname):
- if frommapname not in database.mapfrom:
- raise Exception("Unknown map %s, expected one of %s" % (
- frommapname, ", ".join(database.mapfrom.keys())))
- if tomapname not in database.mapname:
- raise Exception("Unknown map %s, expected one of %s" % (
- tomapname, ", ".join(database.mapname.keys())))
-
- tolinux = database.mapfrom[frommapname]
- fromlinux = database.mapname[tomapname]
-
- if varname is None:
- varname = "name_map_%s_to_%s" % (frommapname, tomapname)
-
- keys = list(tolinux.keys())
- keys.sort()
- if type(keys[0]) == int:
- keys = range(keys[-1] + 1)
-
- if type(keys[0]) == int:
- fromtype = self.TYPE_INT
- else:
- fromtype = self.TYPE_STRING
-
- self._array_start(varname, len(keys), None, fromtype, self.TYPE_STRING)
-
- for src in keys:
- linux = tolinux.get(src, None)
- if linux is None:
- dst = None
- else:
- dst = fromlinux.get(linux, None)
-
- comment = "%s -> %s -> %s" % (self._label(database, frommapname, src, linux),
- self._label(database, Database.MAP_LINUX, linux, linux),
- self._label(database, tomapname, dst, linux))
- self._array_entry(src, dst, comment, fromtype, self.TYPE_STRING)
- self._array_end(fromtype, self.TYPE_STRING)
-
- def generate_name_table(self, varname, database, mapname):
- if mapname not in database.mapname:
- raise Exception("Unknown map %s, expected one of %s" % (
- mapname, ", ".join(database.mapname.keys())))
-
- keys = list(database.mapto[Database.MAP_LINUX].keys())
- keys.sort()
- names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for key in keys]
-
- if varname is None:
- varname = "name_table_%s" % mapname
-
- self._array_start(varname, len(keys), None, self.TYPE_INT, self.TYPE_STRING)
-
- for i in range(len(keys)):
- key = keys[i]
- dst = database.mapname[mapname].get(key, None)
- self._array_entry(i, dst, names[i], self.TYPE_INT, self.TYPE_STRING)
-
- self._array_end(self.TYPE_INT, self.TYPE_STRING)
-
- def _label(self, database, mapname, val, linux):
- if mapname in database.mapname:
- return "%s:%s (%s)" % (mapname, val, database.mapname[mapname].get(linux, "unnamed"))
- else:
- return "%s:%s" % (mapname, val)
-
-class LanguageDocGenerator(LanguageGenerator):
-
- def _array_start_name_doc(self, varname, namemap):
- raise NotImplementedError()
-
- def _array_start_code_doc(self, varname, namemap, codemap):
- raise NotImplementedError()
-
- def _array_end(self):
- raise NotImplementedError()
-
- def _array_name_entry(self, value, name):
- raise NotImplementedError()
-
- def _array_code_entry(self, value, name):
- raise NotImplementedError()
-
- def generate_name_docs(self, title, subtitle, database, mapname):
- if mapname not in database.mapname:
- raise Exception("Unknown map %s, expected one of %s" % (
- mapname, ", ".join(database.mapname.keys())))
-
- keys = list(database.mapto[Database.MAP_LINUX].keys())
- keys.sort()
- names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for key in keys]
-
- if title is None:
- title = mapname
- if subtitle is None:
- subtitle = "Docs for %s" % mapname
-
- self._array_start_name_doc(title, subtitle, 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, title, subtitle, 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 = list(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 title is None:
- title = mapname
- if subtitle is None:
- subtitle = "Docs for %s" % mapname
-
- self._array_start_code_doc(title, subtitle, 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 StdCLanguageGenerator(CLanguageGenerator):
-
- def __init__(self):
- super(StdCLanguageGenerator, self).__init__("unsigned short", "char *", "unsigned int")
-
-class GLib2LanguageGenerator(CLanguageGenerator):
-
- def __init__(self):
- super(GLib2LanguageGenerator, self).__init__("guint16", "gchar *", "guint")
-
-class CHeaderLanguageGenerator(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
- if fromtype == self.TYPE_STRING:
- self._length = 0
- else:
- self._length = length
-
- def _array_end(self, fromtype, totype):
- totypename = self.strtypename if totype == self.TYPE_STRING else self.inttypename
- if fromtype == self.TYPE_STRING:
- vartypename = "struct _%s" % self._varname
- print("%s {" % vartypename)
- print(" const %s from;" % self.strtypename)
- print(" const %s to;" % totypename)
- print("};")
- else:
- vartypename = totypename
- if type(self._length) == str:
- print("extern const %s %s[%s];" % (vartypename, self._varname, self._length))
- else:
- print("extern const %s %s[%d];" % (vartypename, self._varname, self._length))
- print("extern const %s %s_len;" % (self.lentypename, self._varname))
-
- def _array_entry(self, index, value, comment, fromtype, totype):
- if value is None:
- return
- if fromtype == self.TYPE_STRING:
- self._length += 1
-
-class StdCHeaderLanguageGenerator(CHeaderLanguageGenerator):
-
- def __init__(self):
- super(StdCHeaderLanguageGenerator, self).__init__("unsigned short", "char *", "unsigned int")
-
-class GLib2HeaderLanguageGenerator(CHeaderLanguageGenerator):
-
- def __init__(self):
- super(GLib2HeaderLanguageGenerator, self).__init__("guint16", "gchar *", "guint")
-
-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("extern const std::vector<%s> %s;" % (totypename, varname));
- print("const std::vector<%s> %s = {" % (totypename, varname))
- else:
- print("#include <map>")
- print("#include <string>")
- print("extern const std::map<const std::string, %s> %s;" % (totypename, varname))
- 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 StdCppLanguageGenerator(CppLanguageGenerator):
-
- def __init__(self):
- super(StdCppLanguageGenerator, self).__init__("unsigned short", "char *", "unsigned int")
-
-class CppHeaderLanguageGenerator(CHeaderLanguageGenerator):
-
- 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("extern const std::vector<%s> %s;" % (totypename, varname));
- else:
- print("#include <map>")
- print("#include <string>")
- print("extern const std::map<const std::string, %s> %s;" % (totypename, varname))
-
- def _array_end(self, fromtype, totype):
- pass
-
- # designated initializers not available in C++
- def _array_entry(self, index, value, comment, fromtype, totype):
- pass
-
-class StdCppHeaderLanguageGenerator(CppHeaderLanguageGenerator):
-
- def __init__(self):
- super(StdCppHeaderLanguageGenerator, self).__init__("unsigned short", "char *", "unsigned int")
-
-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, title, subtitle, namemap):
- print("=head1 NAME")
- print("")
- print("%s - %s" % (title, subtitle))
- print("")
- print("=head1 DESCRIPTION")
- 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, title, subtitle, codemap, namemap):
- print("=head1 NAME")
- print("")
- print("%s - %s" % (title, subtitle))
- print("")
- print("=head1 DESCRIPTION")
- 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("")
-
-class RSTLanguageGenerator(LanguageDocGenerator):
-
- def _boilerplate(self, lines):
- print("..")
- for line in lines:
- print(" %s" % line)
- print("")
-
- def _array_start_name_doc(self, title, subtitle, namemap):
- print("=" * len(title))
- print(title)
- print("=" * len(title))
- print("")
- print("-" * len(subtitle))
- print(subtitle)
- print("-" * len(subtitle))
- print("")
- print(":Manual section: 7")
- print(":Manual group: Virtualization Support")
- print("")
- print("DESCRIPTION")
- print("===========")
- print("List of %s key code names, with corresponding key code values" % namemap)
- print("")
-
- def _array_start_code_doc(self, title, subtitle, codemap, namemap):
- print("=" * len(title))
- print(title)
- print("=" * len(title))
- print("")
- print("-" * len(subtitle))
- print(subtitle)
- print("-" * len(subtitle))
- print("")
- print(":Manual section: 7")
- print(":Manual group: Virtualization Support")
- print("")
- print("DESCRIPTION")
- print("===========")
- print("List of %s key code values, with corresponding %s key code names" % (codemap, namemap))
- print("")
-
- def _array_end(self):
- print("")
-
- def _array_name_entry(self, value, name):
- print("* %s" % name)
- print("")
- print(" Key value %d (0x%x)" % (value, value))
- print("")
-
- def _array_code_entry(self, value, name):
- print("* %d (0x%x)" % (value, value))
- print("")
- print(" Key name %s" % name)
- print("")
-
-SRC_GENERATORS = {
- "stdc": StdCLanguageGenerator(),
- "stdc-header": StdCHeaderLanguageGenerator(),
- "stdc++": StdCppLanguageGenerator(),
- "stdc++-header": StdCppHeaderLanguageGenerator(),
- "glib2": GLib2LanguageGenerator(),
- "glib2-header": GLib2HeaderLanguageGenerator(),
- "python2": PythonLanguageGenerator(),
- "python3": PythonLanguageGenerator(),
- "perl": PerlLanguageGenerator(),
- "js": JavaScriptLanguageGenerator(),
-}
-DOC_GENERATORS = {
- "pod": PodLanguageGenerator(),
- "rst": RSTLanguageGenerator(),
-}
-
-def code_map(args):
- database = Database()
- database.load(args.keymaps)
-
- cliargs = ["keymap-gen", "code-map", "--lang=%s" % args.lang]
- if args.varname is not None:
- cliargs.append("--varname=%s" % args.varname)
- cliargs.extend(["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", "code-table", "--lang=%s" % args.lang]
- if args.varname is not None:
- cliargs.append("--varname=%s" % args.varname)
- cliargs.extend(["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", "name-map", "--lang=%s" % args.lang]
- if args.varname is not None:
- cliargs.append("--varname=%s" % args.varname)
- cliargs.extend(["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", "name-table", "--lang=%s" % args.lang]
- if args.varname is not None:
- cliargs.append("--varname=%s" % args.varname)
- cliargs.extend(["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", "code-docs", "--lang=%s" % args.lang]
- if args.title is not None:
- cliargs.append("--title=%s" % args.title)
- if args.subtitle is not None:
- cliargs.append("--subtitle=%s" % args.subtitle)
- cliargs.extend(["keymaps.csv", args.mapname])
- DOC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))
-
- DOC_GENERATORS[args.lang].generate_code_docs(args.title, args.subtitle, database, args.mapname)
-
-def name_docs(args):
- database = Database()
- database.load(args.keymaps)
-
-
- cliargs = ["keymap-gen", "name-docs", "--lang=%s" % args.lang]
- if args.title is not None:
- cliargs.append("--title=%s" % args.title)
- if args.subtitle is not None:
- cliargs.append("--subtitle=%s" % args.subtitle)
- cliargs.extend(["keymaps.csv", args.mapname])
- DOC_GENERATORS[args.lang].generate_header(database, " ".join(cliargs))
-
- DOC_GENERATORS[args.lang].generate_name_docs(args.title, args.subtitle, 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()
-
- subparsers = parser.add_subparsers(help="sub-command help")
-
- codemapparser = subparsers.add_parser("code-map", help="Generate a mapping between code tables")
- codemapparser.add_argument("--varname", default=None, help="Data variable name")
- codemapparser.add_argument("--lang", default="stdc",
- help="Output language (%s)" % (
- ",".join(SRC_GENERATORS.keys())))
- 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("--lang", default="stdc",
- help="Output language (%s)" % (
- ",".join(SRC_GENERATORS.keys())))
- codetableparser.add_argument("--varname", default=None, help="Data variable name")
- 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("--lang", default="stdc",
- help="Output language (%s)" % (
- ",".join(SRC_GENERATORS.keys())))
- namemapparser.add_argument("--varname", default=None, help="Data variable name")
- 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("--lang", default="stdc",
- help="Output language, (%s)" % (
- ",".join(SRC_GENERATORS.keys())))
- nametableparser.add_argument("--varname", default=None, help="Data variable name")
- 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("--lang", default="pod",
- help="Output language (%s)" % (
- ",".join(DOC_GENERATORS.keys())))
- codedocsparser.add_argument("--title", default=None, help="Document title")
- codedocsparser.add_argument("--subtitle", default=None, help="Document subtitle")
- 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("--lang", default="pod",
- help="Output language (%s)" % (
- ",".join(DOC_GENERATORS.keys())))
- namedocsparser.add_argument("--title", default=None, help="Document title")
- namedocsparser.add_argument("--subtitle", default=None, help="Document subtitle")
- 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()
--
2.39.2
More information about the pve-devel
mailing list