summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter.hutterer@who-t.net>2019-08-30 11:07:53 +1000
committerPeter Hutterer <peter.hutterer@who-t.net>2019-11-14 05:06:13 +0000
commit46116703552ca2adeda65ace8581eb4570b9cb88 (patch)
tree01a9b7240cb5eaee767f26c409482fdc270d1780
parent39850473386d39aacf530850751caa013a6d8f0a (diff)
rules: replace the merge.sh with a python script
Easier to read and comprehend, but also safer to use because it's harder to mix up the headers. Previously, the HDR file would have the list of section headers and had to be called in the right order using HDR in the file list in the Makefile.am. Let's move the section headers to the files themselves where it's more obvious if they're ever wrong and make the script include them as required. The include order is kept as-is for now so that the final evdev/base rules files are identical. Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--.gitlab-ci.yml2
-rw-r--r--configure.ac1
-rw-r--r--rules/HDR34
-rw-r--r--rules/Makefile.am348
-rw-r--r--rules/base.l1_k.part1
-rw-r--r--rules/base.l1o_s.part1
-rw-r--r--rules/base.l2o_s.part1
-rw-r--r--rules/base.l3o_s.part1
-rw-r--r--rules/base.l4o_s.part1
-rw-r--r--rules/base.l_k.part1
-rw-r--r--rules/base.lo_s.part1
-rw-r--r--rules/base.m_g.part1
-rw-r--r--rules/base.m_k.part1
-rw-r--r--rules/base.m_s.part1
-rw-r--r--rules/base.m_t.part1
-rw-r--r--rules/base.ml1_c.part1
-rw-r--r--rules/base.ml1_s.part1
-rw-r--r--rules/base.ml2_s.part1
-rw-r--r--rules/base.ml3_s.part1
-rw-r--r--rules/base.ml4_s.part1
-rw-r--r--rules/base.ml_c.part1
-rw-r--r--rules/base.ml_g.part1
-rw-r--r--rules/base.ml_s.part1
-rw-r--r--rules/base.ml_s1.part1
-rw-r--r--rules/base.mlv_s.part1
-rw-r--r--rules/base.o_c.part1
-rw-r--r--rules/base.o_k.part1
-rw-r--r--rules/base.o_s.part1
-rw-r--r--rules/base.o_t.part1
-rwxr-xr-xrules/bin/ml1_s.sh2
-rwxr-xr-xrules/bin/ml1v1_s.sh2
-rwxr-xr-xrules/bin/ml1v_s.sh2
-rwxr-xr-xrules/bin/ml_s.sh2
-rwxr-xr-xrules/bin/mln_s.sh2
-rwxr-xr-xrules/bin/mlnvn_s.sh2
-rwxr-xr-xrules/bin/mlv_s.sh2
-rw-r--r--rules/compat/base.l1v1_c.part1
-rw-r--r--rules/compat/base.l2v2_c.part1
-rw-r--r--rules/compat/base.l3v3_c.part1
-rw-r--r--rules/compat/base.l4v4_c.part1
-rw-r--r--rules/compat/base.lv_c.part1
-rw-r--r--rules/compat/base.o_s.part1
-rw-r--r--rules/evdev.m_k.part1
-rw-r--r--rules/evdev.m_s.part1
-rwxr-xr-xrules/merge.py50
-rwxr-xr-xrules/merge.sh35
46 files changed, 256 insertions, 261 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 5326c2c5..3d460932 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,7 +1,7 @@
# vim: set expandtab shiftwidth=2 tabstop=8 textwidth=0:
variables:
- ARCH_PKGS: 'xorg-util-macros autoconf automake make gettext pkg-config gcc grep m4'
+ ARCH_PKGS: 'xorg-util-macros autoconf automake make gettext pkg-config gcc grep m4 python'
BUILDDIR: '_build'
INSTDIR: '$HOME/_inst'
CONFIGURE_ARGS: ''
diff --git a/configure.ac b/configure.ac
index c12d79f7..8cca8c60 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,6 +10,7 @@ XORG_MACROS_VERSION(1.12)
XORG_MANPAGE_SECTIONS
XORG_WITH_XSLTPROC
AC_PROG_SED
+AM_PATH_PYTHON([3.0])
AC_SUBST(VERSION)
diff --git a/rules/HDR b/rules/HDR
deleted file mode 100644
index 9ee3e39d..00000000
--- a/rules/HDR
+++ /dev/null
@@ -1,34 +0,0 @@
-! model = keycodes
-! layout[1] = keycodes
-! layout = keycodes
-! option = keycodes
-! model layout = geometry
-! model = geometry
-! model layout variant = symbols
-! model layout = symbols
-! model layout[1] = symbols
-! model layout[1] variant[1] = symbols
-! model layout[2] = symbols
-! model layout[3] = symbols
-! model layout[4] = symbols
-! model layout[2] variant[2] = symbols
-! model layout[3] variant[3] = symbols
-! model layout[4] variant[4] = symbols
-! model = symbols
-! model layout = symbols
-! layout variant = compat
-! layout[1] variant[1] = compat
-! layout[2] variant[2] = compat
-! layout[3] variant[3] = compat
-! layout[4] variant[4] = compat
-! model layout = compat
-! model layout[1] = compat
-! model = types
-! layout option = symbols
-! layout[1] option = symbols
-! layout[2] option = symbols
-! layout[3] option = symbols
-! layout[4] option = symbols
-! option = symbols
-! option = compat
-! option = types
diff --git a/rules/Makefile.am b/rules/Makefile.am
index cb408aa2..36e01165 100644
--- a/rules/Makefile.am
+++ b/rules/Makefile.am
@@ -22,191 +22,171 @@ endif
if USE_COMPAT_RULES
-base_parts = base.hdr.part base.lists.part \
-base.lists.base.part \
-compat/base.lists.part \
-HDR base.m_k.part \
-HDR base.l1_k.part \
-HDR base.l_k.part \
-HDR base.o_k.part \
-HDR base.ml_g.part \
-HDR base.m_g.part \
-HDR compat/base.mlv_s.part base.mlv_s.part \
-HDR compat/base.ml_s.part base.ml_s.part \
-HDR compat/base.ml1_s.part base.ml1_s.part \
-HDR compat/base.ml1v1_s.part \
-HDR compat/base.ml2_s.part base.ml2_s.part \
-HDR compat/base.ml3_s.part base.ml3_s.part \
-HDR compat/base.ml4_s.part base.ml4_s.part \
-HDR compat/base.ml2v2_s.part \
-HDR compat/base.ml3v3_s.part \
-HDR compat/base.ml4v4_s.part \
-HDR base.m_s.part \
-HDR base.ml_s1.part \
-HDR compat/base.lv_c.part \
-HDR compat/base.l1v1_c.part \
-HDR compat/base.l2v2_c.part \
-HDR compat/base.l3v3_c.part \
-HDR compat/base.l4v4_c.part \
-HDR base.ml_c.part \
-HDR base.ml1_c.part \
-HDR base.m_t.part \
-HDR base.lo_s.part \
-HDR base.l1o_s.part \
-HDR base.l2o_s.part \
-HDR base.l3o_s.part \
-HDR base.l4o_s.part \
-HDR compat/base.o_s.part base.o_s.part \
-HDR base.o_c.part \
-HDR base.o_t.part
-
-evdev_parts = base.hdr.part base.lists.part \
-evdev.lists.part \
-compat/base.lists.part \
-HDR evdev.m_k.part \
-HDR base.l1_k.part \
-HDR base.l_k.part \
-HDR base.o_k.part \
-HDR base.ml_g.part \
-HDR base.m_g.part \
-HDR compat/base.mlv_s.part base.mlv_s.part \
-HDR compat/base.ml_s.part base.ml_s.part \
-HDR compat/base.ml1_s.part base.ml1_s.part \
-HDR compat/base.ml1v1_s.part \
-HDR compat/base.ml2_s.part base.ml2_s.part \
-HDR compat/base.ml3_s.part base.ml3_s.part \
-HDR compat/base.ml4_s.part base.ml4_s.part \
-HDR compat/base.ml2v2_s.part \
-HDR compat/base.ml3v3_s.part \
-HDR compat/base.ml4v4_s.part \
-HDR evdev.m_s.part \
-HDR \
-HDR compat/base.lv_c.part \
-HDR compat/base.l1v1_c.part \
-HDR compat/base.l2v2_c.part \
-HDR compat/base.l3v3_c.part \
-HDR compat/base.l4v4_c.part \
-HDR base.ml_c.part \
-HDR base.ml1_c.part \
-HDR base.m_t.part \
-HDR base.lo_s.part \
-HDR base.l1o_s.part \
-HDR base.l2o_s.part \
-HDR base.l3o_s.part \
-HDR base.l4o_s.part \
-HDR compat/base.o_s.part base.o_s.part \
-HDR base.o_c.part \
-HDR base.o_t.part
+base_parts = \
+ base.hdr.part base.lists.part \
+ base.lists.base.part \
+ compat/base.lists.part \
+ base.m_k.part \
+ base.l1_k.part \
+ base.l_k.part \
+ base.o_k.part \
+ base.ml_g.part \
+ base.m_g.part \
+ compat/base.mlv_s.part base.mlv_s.part \
+ compat/base.ml_s.part base.ml_s.part \
+ compat/base.ml1_s.part base.ml1_s.part \
+ compat/base.ml1v1_s.part \
+ compat/base.ml2_s.part base.ml2_s.part \
+ compat/base.ml3_s.part base.ml3_s.part \
+ compat/base.ml4_s.part base.ml4_s.part \
+ compat/base.ml2v2_s.part \
+ compat/base.ml3v3_s.part \
+ compat/base.ml4v4_s.part \
+ base.m_s.part \
+ base.ml_s1.part \
+ compat/base.lv_c.part \
+ compat/base.l1v1_c.part \
+ compat/base.l2v2_c.part \
+ compat/base.l3v3_c.part \
+ compat/base.l4v4_c.part \
+ base.ml_c.part \
+ base.ml1_c.part \
+ base.m_t.part \
+ base.lo_s.part \
+ base.l1o_s.part \
+ base.l2o_s.part \
+ base.l3o_s.part \
+ base.l4o_s.part \
+ compat/base.o_s.part base.o_s.part \
+ base.o_c.part \
+ base.o_t.part
+
+evdev_parts = \
+ base.hdr.part base.lists.part \
+ evdev.lists.part \
+ compat/base.lists.part \
+ evdev.m_k.part \
+ base.l1_k.part \
+ base.l_k.part \
+ base.o_k.part \
+ base.ml_g.part \
+ base.m_g.part \
+ compat/base.mlv_s.part base.mlv_s.part \
+ compat/base.ml_s.part base.ml_s.part \
+ compat/base.ml1_s.part base.ml1_s.part \
+ compat/base.ml1v1_s.part \
+ compat/base.ml2_s.part base.ml2_s.part \
+ compat/base.ml3_s.part base.ml3_s.part \
+ compat/base.ml4_s.part base.ml4_s.part \
+ compat/base.ml2v2_s.part \
+ compat/base.ml3v3_s.part \
+ compat/base.ml4v4_s.part \
+ evdev.m_s.part \
+ compat/base.lv_c.part \
+ compat/base.l1v1_c.part \
+ compat/base.l2v2_c.part \
+ compat/base.l3v3_c.part \
+ compat/base.l4v4_c.part \
+ base.ml_c.part \
+ base.ml1_c.part \
+ base.m_t.part \
+ base.lo_s.part \
+ base.l1o_s.part \
+ base.l2o_s.part \
+ base.l3o_s.part \
+ base.l4o_s.part \
+ compat/base.o_s.part base.o_s.part \
+ base.o_c.part \
+ base.o_t.part
else
-base_parts = base.hdr.part base.lists.part \
-base.lists.base.part \
-HDR base.m_k.part \
-HDR base.l1_k.part \
-HDR base.l_k.part \
-HDR \
-HDR base.ml_g.part \
-HDR base.m_g.part \
-HDR base.mlv_s.part \
-HDR base.ml_s.part \
-HDR base.ml1_s.part \
-HDR \
-HDR base.ml2_s.part \
-HDR base.ml3_s.part \
-HDR base.ml4_s.part \
-HDR \
-HDR \
-HDR \
-HDR base.m_s.part \
-HDR base.ml_s1.part \
-HDR \
-HDR \
-HDR \
-HDR \
-HDR \
-HDR base.ml_c.part \
-HDR base.ml1_c.part \
-HDR base.m_t.part \
-HDR \
-HDR base.l1o_s.part \
-HDR base.l2o_s.part \
-HDR base.l3o_s.part \
-HDR base.l4o_s.part \
-HDR base.o_s.part \
-HDR base.o_c.part \
-HDR base.o_t.part
-
-evdev_parts = base.hdr.part base.lists.part \
-evdev.lists.part \
-HDR evdev.m_k.part \
-HDR base.l1_k.part \
-HDR base.l_k.part \
-HDR \
-HDR base.ml_g.part \
-HDR base.m_g.part \
-HDR base.mlv_s.part \
-HDR base.ml_s.part \
-HDR base.ml1_s.part \
-HDR \
-HDR base.ml2_s.part \
-HDR base.ml3_s.part \
-HDR base.ml4_s.part \
-HDR \
-HDR \
-HDR \
-HDR evdev.m_s.part \
-HDR \
-HDR \
-HDR \
-HDR \
-HDR \
-HDR \
-HDR base.ml_c.part \
-HDR base.ml1_c.part \
-HDR base.m_t.part \
-HDR \
-HDR base.l1o_s.part \
-HDR base.l2o_s.part \
-HDR base.l3o_s.part \
-HDR base.l4o_s.part \
-HDR base.o_s.part \
-HDR base.o_c.part \
-HDR base.o_t.part
+base_parts = \
+ base.hdr.part base.lists.part \
+ base.lists.base.part \
+ base.m_k.part \
+ base.l1_k.part \
+ base.l_k.part \
+ base.ml_g.part \
+ base.m_g.part \
+ base.mlv_s.part \
+ base.ml_s.part \
+ base.ml1_s.part \
+ base.ml2_s.part \
+ base.ml3_s.part \
+ base.ml4_s.part \
+ base.m_s.part \
+ base.ml_s1.part \
+ base.ml_c.part \
+ base.ml1_c.part \
+ base.m_t.part \
+ base.l1o_s.part \
+ base.l2o_s.part \
+ base.l3o_s.part \
+ base.l4o_s.part \
+ base.o_s.part \
+ base.o_c.part \
+ base.o_t.part
+
+evdev_parts = \
+ base.hdr.part base.lists.part \
+ evdev.lists.part \
+ evdev.m_k.part \
+ base.l1_k.part \
+ base.l_k.part \
+ base.ml_g.part \
+ base.m_g.part \
+ base.mlv_s.part \
+ base.ml_s.part \
+ base.ml1_s.part \
+ base.ml2_s.part \
+ base.ml3_s.part \
+ base.ml4_s.part \
+ evdev.m_s.part \
+ base.ml_c.part \
+ base.ml1_c.part \
+ base.m_t.part \
+ base.l1o_s.part \
+ base.l2o_s.part \
+ base.l3o_s.part \
+ base.l4o_s.part \
+ base.o_s.part \
+ base.o_c.part \
+ base.o_t.part
endif
-all_parts_dist = HDR base.hdr.part \
-base.lists.part \
-base.lists.base.part \
-evdev.lists.part \
-base.m_k.part \
-base.l1_k.part \
-base.l_k.part \
-base.o_k.part \
-base.ml_g.part \
-base.m_g.part \
-base.mlv_s.part \
-base.ml_s.part \
-base.ml1_s.part \
-base.ml2_s.part \
-base.ml3_s.part \
-base.ml4_s.part \
-base.m_s.part \
-base.ml_s1.part \
-base.ml_c.part \
-base.ml1_c.part \
-base.m_t.part \
-base.lo_s.part \
-base.l1o_s.part \
-base.l2o_s.part \
-base.l3o_s.part \
-base.l4o_s.part \
-base.o_s.part \
-base.o_c.part \
-base.o_t.part \
-evdev.m_k.part \
-evdev.m_s.part
+all_parts_dist = base.hdr.part \
+ base.lists.part \
+ base.lists.base.part \
+ evdev.lists.part \
+ base.m_k.part \
+ base.l1_k.part \
+ base.l_k.part \
+ base.o_k.part \
+ base.ml_g.part \
+ base.m_g.part \
+ base.mlv_s.part \
+ base.ml_s.part \
+ base.ml1_s.part \
+ base.ml2_s.part \
+ base.ml3_s.part \
+ base.ml4_s.part \
+ base.m_s.part \
+ base.ml_s1.part \
+ base.ml_c.part \
+ base.ml1_c.part \
+ base.m_t.part \
+ base.lo_s.part \
+ base.l1o_s.part \
+ base.l2o_s.part \
+ base.l3o_s.part \
+ base.l4o_s.part \
+ base.o_s.part \
+ base.o_c.part \
+ base.o_t.part \
+ evdev.m_k.part \
+ evdev.m_s.part
rules_files = base evdev xfree98
@@ -217,11 +197,11 @@ SUFFIXES = .xml .lst
.xml.lst:
perl $(srcdir)/xml2lst.pl < $< > $@
-base: $(base_parts)
- HDR="$(srcdir)/HDR" $(srcdir)/merge.sh $@ $(base_parts)
+base: $(base_parts) merge.py
+ $(srcdir)/merge.py $@ $(srcdir) $(builddir) $(base_parts)
-evdev: $(evdev_parts)
- HDR="$(srcdir)/HDR" $(srcdir)/merge.sh $@ $(evdev_parts)
+evdev: $(evdev_parts) merge.py
+ $(srcdir)/merge.py $@ $(srcdir) $(builddir) $(evdev_parts)
dist_files = xkb.dtd xkb.its README
@@ -237,7 +217,7 @@ $(srcdir)/evdev.extras.xml: base.extras.xml
EXTRA_DIST= $(xml_DATA) xfree98 \
$(all_parts_dist) \
- xml2lst.pl merge.sh $(dist_files)
+ xml2lst.pl merge.py $(dist_files)
CLEANFILES = base base.lst evdev evdev.lst
diff --git a/rules/base.l1_k.part b/rules/base.l1_k.part
index 91b77539..3f2146af 100644
--- a/rules/base.l1_k.part
+++ b/rules/base.l1_k.part
@@ -1,3 +1,4 @@
+! layout[1] = keycodes
$azerty = +aliases(azerty)
$qwertz = +aliases(qwertz)
* = +aliases(qwerty)
diff --git a/rules/base.l1o_s.part b/rules/base.l1o_s.part
index 592fab27..42f4a283 100644
--- a/rules/base.l1o_s.part
+++ b/rules/base.l1o_s.part
@@ -1,2 +1,3 @@
+! layout[1] option = symbols
$threelevellayouts grp:alts_toggle = +level3(ralt_switch_for_alts_toggle):1
* misc:typo = +typo(base):1
diff --git a/rules/base.l2o_s.part b/rules/base.l2o_s.part
index aac680e9..87bdacdd 100644
--- a/rules/base.l2o_s.part
+++ b/rules/base.l2o_s.part
@@ -1,2 +1,3 @@
+! layout[2] option = symbols
$threelevellayouts grp:alts_toggle = +level3(ralt_switch_for_alts_toggle):2
* misc:typo = +typo(base):2
diff --git a/rules/base.l3o_s.part b/rules/base.l3o_s.part
index 1010e2e0..45b7bc73 100644
--- a/rules/base.l3o_s.part
+++ b/rules/base.l3o_s.part
@@ -1,2 +1,3 @@
+! layout[3] option = symbols
$threelevellayouts grp:alts_toggle = +level3(ralt_switch_for_alts_toggle):3
* misc:typo = +typo(base):3
diff --git a/rules/base.l4o_s.part b/rules/base.l4o_s.part
index 49650ad9..98ab19f0 100644
--- a/rules/base.l4o_s.part
+++ b/rules/base.l4o_s.part
@@ -1,2 +1,3 @@
+! layout[4] option = symbols
$threelevellayouts grp:alts_toggle = +level3(ralt_switch_for_alts_toggle):4
* misc:typo = +typo(base):4
diff --git a/rules/base.l_k.part b/rules/base.l_k.part
index 91b77539..a0955177 100644
--- a/rules/base.l_k.part
+++ b/rules/base.l_k.part
@@ -1,3 +1,4 @@
+! layout = keycodes
$azerty = +aliases(azerty)
$qwertz = +aliases(qwertz)
* = +aliases(qwerty)
diff --git a/rules/base.lo_s.part b/rules/base.lo_s.part
index dee7b6da..6bcb4347 100644
--- a/rules/base.lo_s.part
+++ b/rules/base.lo_s.part
@@ -1,2 +1,3 @@
+! layout option = symbols
$threelevellayouts grp:alts_toggle = +level3(ralt_switch_for_alts_toggle)
* misc:typo = +typo(base)
diff --git a/rules/base.m_g.part b/rules/base.m_g.part
index 74001051..6b3285f9 100644
--- a/rules/base.m_g.part
+++ b/rules/base.m_g.part
@@ -1,3 +1,4 @@
+! model = geometry
microsoftelite = microsoft(elite)
$msmodels = microsoft(natural)
dell101 = dell(dell101)
diff --git a/rules/base.m_k.part b/rules/base.m_k.part
index ebccd3ea..08c5c517 100644
--- a/rules/base.m_k.part
+++ b/rules/base.m_k.part
@@ -1,3 +1,4 @@
+! model = keycodes
amiga = amiga(de)
ataritt = ataritt(de)
empty = empty
diff --git a/rules/base.m_s.part b/rules/base.m_s.part
index e4e73cd9..58ed7b68 100644
--- a/rules/base.m_s.part
+++ b/rules/base.m_s.part
@@ -1,3 +1,4 @@
+! model = symbols
a4techKB21 = +inet(media_nav_common)
a4techKBS8 = +inet(media_nav_acpi_common)
a4_rfkb23 = +inet(media_nav_acpi_common)
diff --git a/rules/base.m_t.part b/rules/base.m_t.part
index 9669d6b3..2a1de2da 100644
--- a/rules/base.m_t.part
+++ b/rules/base.m_t.part
@@ -1,3 +1,4 @@
+! model = types
$macs = complete+numpad(mac)
$applealu = complete+numpad(mac)
$nokiamodels = complete+nokia
diff --git a/rules/base.ml1_c.part b/rules/base.ml1_c.part
index f59e596d..874e4e34 100644
--- a/rules/base.ml1_c.part
+++ b/rules/base.ml1_c.part
@@ -1 +1,2 @@
+! model layout[1] = compat
* * = complete
diff --git a/rules/base.ml1_s.part b/rules/base.ml1_s.part
index ae07bfa1..667eb19f 100644
--- a/rules/base.ml1_s.part
+++ b/rules/base.ml1_s.part
@@ -1,3 +1,4 @@
+! model layout[1] = symbols
ataritt * = xfree68_vndr/ataritt(us)+%l[1]%(v[1])
amiga * = xfree68_vndr/amiga(usa1)+%l[1]%(v[1])
jollasbj * = jolla_vndr/sbj(common)+%l[1]%(v[1])
diff --git a/rules/base.ml2_s.part b/rules/base.ml2_s.part
index e80d7cf8..0aaa8d63 100644
--- a/rules/base.ml2_s.part
+++ b/rules/base.ml2_s.part
@@ -1,3 +1,4 @@
+! model layout[2] = symbols
nokiarx51 cz(qwerty) = +nokia_vndr/rx-51(cz_qwerty):2
nokiarx51 * = +nokia_vndr/rx-51(%l[2]%_v[2]):2
$sun $sun_custom = +sun_vndr/%l[2]%(v[2]):2
diff --git a/rules/base.ml3_s.part b/rules/base.ml3_s.part
index efe7cf17..ccd8f920 100644
--- a/rules/base.ml3_s.part
+++ b/rules/base.ml3_s.part
@@ -1,3 +1,4 @@
+! model layout[3] = symbols
nokiarx51 cz(qwerty) = +nokia_vndr/rx-51(cz_qwerty):3
nokiarx51 * = +nokia_vndr/rx-51(%l[3]%_v[3]):3
$sun $sun_custom = +sun_vndr/%l[3]%(v[3]):3
diff --git a/rules/base.ml4_s.part b/rules/base.ml4_s.part
index 00ba445d..34693c56 100644
--- a/rules/base.ml4_s.part
+++ b/rules/base.ml4_s.part
@@ -1,3 +1,4 @@
+! model layout[4] = symbols
nokiarx51 cz(qwerty) = +nokia_vndr/rx-51(cz_qwerty):4
nokiarx51 * = +nokia_vndr/rx-51(%l[4]%_v[4]):4
$sun $sun_custom = +sun_vndr/%l[4]%(v[4]):4
diff --git a/rules/base.ml_c.part b/rules/base.ml_c.part
index 793ebe16..91fb1896 100644
--- a/rules/base.ml_c.part
+++ b/rules/base.ml_c.part
@@ -1,3 +1,4 @@
+! model layout = compat
pc98 nec_vndr/jp = pc98(basic)
* jp = complete+japan
olpc * = olpc
diff --git a/rules/base.ml_g.part b/rules/base.ml_g.part
index e66bb0b5..66cac540 100644
--- a/rules/base.ml_g.part
+++ b/rules/base.ml_g.part
@@ -1 +1,2 @@
+! model layout = geometry
thinkpad us = thinkpad(us)
diff --git a/rules/base.ml_s.part b/rules/base.ml_s.part
index 481b44a9..7bf3d516 100644
--- a/rules/base.ml_s.part
+++ b/rules/base.ml_s.part
@@ -1,3 +1,4 @@
+! model layout = symbols
ataritt $nonlatin = xfree68_vndr/ataritt(us)+%l%(v):2
ataritt * = xfree68_vndr/ataritt(us)+%l%(v)
amiga $nonlatin = xfree68_vndr/amiga(usa1)+%l%(v):2
diff --git a/rules/base.ml_s1.part b/rules/base.ml_s1.part
index 1a35202d..8c75c39a 100644
--- a/rules/base.ml_s1.part
+++ b/rules/base.ml_s1.part
@@ -1 +1,2 @@
+! model layout = symbols
$inetmediakbds jp = +jp(henkan)
diff --git a/rules/base.mlv_s.part b/rules/base.mlv_s.part
index 1ae11717..b2e50233 100644
--- a/rules/base.mlv_s.part
+++ b/rules/base.mlv_s.part
@@ -1,3 +1,4 @@
+! model layout variant = symbols
classmate us intl = pc+us(classmate-intl)
classmate us alt-intl = pc+us(classmate-alt-intl)
classmate us altgr-intl = pc+us(classmate-altgr-intl)
diff --git a/rules/base.o_c.part b/rules/base.o_c.part
index 504aa40d..d3e8a466 100644
--- a/rules/base.o_c.part
+++ b/rules/base.o_c.part
@@ -1,3 +1,4 @@
+! option = compat
grp_led:num = +lednum(group_lock)
grp_led:caps = +ledcaps(group_lock)
grp_led:scroll = +ledscroll(group_lock)
diff --git a/rules/base.o_k.part b/rules/base.o_k.part
index e69de29b..0c42cd84 100644
--- a/rules/base.o_k.part
+++ b/rules/base.o_k.part
@@ -0,0 +1 @@
+! option = keycodes
diff --git a/rules/base.o_s.part b/rules/base.o_s.part
index 15074eb2..b2a24025 100644
--- a/rules/base.o_s.part
+++ b/rules/base.o_s.part
@@ -1,3 +1,4 @@
+! option = symbols
altwin:menu = +altwin(menu)
altwin:menu_win = +altwin(menu_win)
altwin:meta_alt = +altwin(meta_alt)
diff --git a/rules/base.o_t.part b/rules/base.o_t.part
index e0d4b15e..a43a993f 100644
--- a/rules/base.o_t.part
+++ b/rules/base.o_t.part
@@ -1,3 +1,4 @@
+! option = types
caps:internal = +caps(internal)
caps:internal_nocancel = +caps(internal_nocancel)
caps:shift = +caps(shift)
diff --git a/rules/bin/ml1_s.sh b/rules/bin/ml1_s.sh
index b2d22243..ba4fde76 100755
--- a/rules/bin/ml1_s.sh
+++ b/rules/bin/ml1_s.sh
@@ -3,7 +3,7 @@
INDIR=$1
OUTFILE=base.ml1_s.part
-> $OUTFILE
+echo "! model layout[1] = symbols" > $OUTFILE
awk '{
if (index($2, "(") == 0) {
diff --git a/rules/bin/ml1v1_s.sh b/rules/bin/ml1v1_s.sh
index 7c2b1a84..685dec05 100755
--- a/rules/bin/ml1v1_s.sh
+++ b/rules/bin/ml1v1_s.sh
@@ -3,7 +3,7 @@
INDIR=$1
OUTFILE=base.ml1v1_s.part
-> $OUTFILE
+echo "! model layout[1] variant[1] = symbols" > $OUTFILE
awk '{
printf " * %s %s = pc+%s(%s)\n", $1, $2, $3, $4;
diff --git a/rules/bin/ml1v_s.sh b/rules/bin/ml1v_s.sh
index 084d4c0b..1df7a654 100755
--- a/rules/bin/ml1v_s.sh
+++ b/rules/bin/ml1v_s.sh
@@ -3,7 +3,7 @@
INDIR=$1
OUTFILE=base.ml1v_s.part
-> $OUTFILE
+echo "! model layout variant = symbols" > $OUTFILE
awk '{
printf " * %s %s = pc+%s(%s)\n", $1, $2, $3, $4;
diff --git a/rules/bin/ml_s.sh b/rules/bin/ml_s.sh
index 666ba870..1e7ae6e0 100755
--- a/rules/bin/ml_s.sh
+++ b/rules/bin/ml_s.sh
@@ -3,7 +3,7 @@
INDIR=$1
OUTFILE=base.ml_s.part
-> $OUTFILE
+echo "! model layout = symbols" > $OUTFILE
awk '{
printf " * %s = pc+%s\n", $1, $2;
diff --git a/rules/bin/mln_s.sh b/rules/bin/mln_s.sh
index 67fd8a06..1eb89e69 100755
--- a/rules/bin/mln_s.sh
+++ b/rules/bin/mln_s.sh
@@ -5,7 +5,7 @@ variant=$1
INDIR=$2
OUTFILE=base.ml${variant}_s.part
-> $OUTFILE
+echo "! model layout[$variant] = symbols" > $OUTFILE
awk '{
if (index($2, "(") == 0) {
diff --git a/rules/bin/mlnvn_s.sh b/rules/bin/mlnvn_s.sh
index 1a5f40f2..287f31f1 100755
--- a/rules/bin/mlnvn_s.sh
+++ b/rules/bin/mlnvn_s.sh
@@ -5,7 +5,7 @@ variant=$1
INDIR=$2
OUTFILE=base.ml${variant}v${variant}_s.part
-> $OUTFILE
+echo "! model layout[$variant] variant[$variant] = symbols" > $OUTFILE
awk '{
printf " * %s %s = +%s(%s):'${variant}'\n", $1, $2, $3, $4;
diff --git a/rules/bin/mlv_s.sh b/rules/bin/mlv_s.sh
index 5b466d59..57d89694 100755
--- a/rules/bin/mlv_s.sh
+++ b/rules/bin/mlv_s.sh
@@ -3,7 +3,7 @@
INDIR=$1
OUTFILE=base.mlv_s.part
-> $OUTFILE
+echo "! model layout variant = symbols" > $OUTFILE
awk '{
printf " * %s %s = pc+%s(%s)\n", $1, $2, $3, $4;
diff --git a/rules/compat/base.l1v1_c.part b/rules/compat/base.l1v1_c.part
index f47473c7..f5ff3a21 100644
--- a/rules/compat/base.l1v1_c.part
+++ b/rules/compat/base.l1v1_c.part
@@ -1,3 +1,4 @@
+! layout[1] variant[1] = compat
de neo = +caps(caps_lock)+misc(assign_shift_left_action)+level5(level5_lock)
de adnw = +caps(caps_lock)+misc(assign_shift_left_action)+level5(level5_lock)
de koy = +caps(caps_lock)+misc(assign_shift_left_action)+level5(level5_lock)
diff --git a/rules/compat/base.l2v2_c.part b/rules/compat/base.l2v2_c.part
index dc10a270..cf6e0f2f 100644
--- a/rules/compat/base.l2v2_c.part
+++ b/rules/compat/base.l2v2_c.part
@@ -1,3 +1,4 @@
+! layout[2] variant[2] = compat
de neo = +caps(caps_lock):2+misc(assign_shift_left_action):2+level5(level5_lock):2
de adnw = +caps(caps_lock):2+misc(assign_shift_left_action):2+level5(level5_lock):2
de koy = +caps(caps_lock):2+misc(assign_shift_left_action):2+level5(level5_lock):2
diff --git a/rules/compat/base.l3v3_c.part b/rules/compat/base.l3v3_c.part
index 8b8d9f93..a015adc9 100644
--- a/rules/compat/base.l3v3_c.part
+++ b/rules/compat/base.l3v3_c.part
@@ -1,3 +1,4 @@
+! layout[3] variant[3] = compat
de neo = +caps(caps_lock):3+misc(assign_shift_left_action):3+level5(level5_lock):3
de adnw = +caps(caps_lock):3+misc(assign_shift_left_action):3+level5(level5_lock):3
de koy = +caps(caps_lock):3+misc(assign_shift_left_action):3+level5(level5_lock):3
diff --git a/rules/compat/base.l4v4_c.part b/rules/compat/base.l4v4_c.part
index ce7480d0..6b7be5f5 100644
--- a/rules/compat/base.l4v4_c.part
+++ b/rules/compat/base.l4v4_c.part
@@ -1,3 +1,4 @@
+! layout[4] variant[4] = compat
de neo = +caps(caps_lock):4+misc(assign_shift_left_action):4+level5(level5_lock):4
de adnw = +caps(caps_lock):4+misc(assign_shift_left_action):4+level5(level5_lock):4
de koy = +caps(caps_lock):4+misc(assign_shift_left_action):4+level5(level5_lock):4
diff --git a/rules/compat/base.lv_c.part b/rules/compat/base.lv_c.part
index 054c4282..ea58f61d 100644
--- a/rules/compat/base.lv_c.part
+++ b/rules/compat/base.lv_c.part
@@ -1,3 +1,4 @@
+! layout variant = compat
de neo = +caps(caps_lock)+misc(assign_shift_left_action)+level5(level5_lock)
de adnw = +caps(caps_lock)+misc(assign_shift_left_action)+level5(level5_lock)
de koy = +caps(caps_lock)+misc(assign_shift_left_action)+level5(level5_lock)
diff --git a/rules/compat/base.o_s.part b/rules/compat/base.o_s.part
index 8f1e9e45..2f16e6a5 100644
--- a/rules/compat/base.o_s.part
+++ b/rules/compat/base.o_s.part
@@ -1 +1,2 @@
+! option = symbols
grp:shift_toggle = +group(shifts_toggle)
diff --git a/rules/evdev.m_k.part b/rules/evdev.m_k.part
index cce7dc0e..2f98057d 100644
--- a/rules/evdev.m_k.part
+++ b/rules/evdev.m_k.part
@@ -1,3 +1,4 @@
+! model = keycodes
applealu_jis = evdev+macintosh(jisevdev)
$jollamodels = evdev+jolla(jolla)
olpc = evdev+olpc(olpc)
diff --git a/rules/evdev.m_s.part b/rules/evdev.m_s.part
index 5852a72c..c79a02e2 100644
--- a/rules/evdev.m_s.part
+++ b/rules/evdev.m_s.part
@@ -1,3 +1,4 @@
+! model = symbols
$evdevkbds = +inet(evdev)+inet(%m)
chromebook = +inet(evdev)+inet(chromebook)
applealu_jis = +inet(evdev)+macintosh_vndr/jp(alujiskeys)
diff --git a/rules/merge.py b/rules/merge.py
new file mode 100755
index 00000000..b8d95334
--- /dev/null
+++ b/rules/merge.py
@@ -0,0 +1,50 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import sys
+
+def merge(dest, files):
+ '''
+ Merge the content of all files into the file dest.
+
+ The first line of each file is an optional section header in the form
+ e.g.
+ ! model = keycodes
+ Where two sections have identical headers, the second header is skipped.
+ '''
+ # section is the group that the next file will be added to, defined
+ # by the header of that file (e.g. ! model = keycodes)
+ section = None
+ for partsfile in files:
+ # files may exist in srcdir or builddir, depending whether they're
+ # generated
+ path = partsfile[0] if os.path.exists(partsfile[0]) else partsfile[1]
+
+ with open(path) as fd:
+ header = fd.readline()
+ if header.startswith('! '):
+ if header != section:
+ section = header
+ dest.write('\n')
+ dest.write(section)
+ else:
+ section = None
+ dest.write(header)
+ dest.write(fd.read())
+
+
+if __name__ == '__main__':
+ parser = argparse.ArgumentParser('rules file merge script')
+ parser.add_argument('dest', type=str)
+ parser.add_argument('srcdir', type=str)
+ parser.add_argument('builddir', type=str)
+ parser.add_argument('files', nargs='+', type=str)
+ ns = parser.parse_args()
+
+ with open(ns.dest, 'w') as fd:
+ basename = os.path.basename(sys.argv[0])
+ fd.write('// DO NOT EDIT THIS FILE - IT WAS AUTOGENERATED BY {} FROM rules/*.part\n'.format(basename))
+ fd.write('//\n')
+ ftuple = lambda f: (os.path.join(ns.builddir, f), os.path.join(ns.srcdir, f))
+ merge(fd, [ftuple(f) for f in ns.files])
diff --git a/rules/merge.sh b/rules/merge.sh
deleted file mode 100755
index 6d15c7e7..00000000
--- a/rules/merge.sh
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/bin/sh
-
-# Usage: merge.sh <output-file> <file1.part> <file2.part> <file3.part> …
-
-INDIR=`dirname $0`
-DEST=$1
-shift
-
-if [ -z "$HDR" ]; then
- HDR="HDR"
-fi
-
-basename=`basename $0`
-echo "// DO NOT EDIT THIS FILE - IT WAS AUTOGENERATED BY $basename FROM rules/*.part" >$DEST
-
-# The HDR file contains the headers for each section in the rules file.
-# This is fed as stdin to the for loop below.
-#
-# Wherever the current file is the literal string "HDR", read the next line
-# from that file append it to $DEST
-# Otherwise, take the filename and append it to $DEST.
-#
-
-for partfile in $*; do
- if [ "$partfile" = "$HDR" ] || [ "$partfile" = "HDR" ]; then
- echo >> $DEST;
- read hdr
- echo "$hdr" >> $DEST
- elif test -f $partfile; then
- cat $partfile >> $DEST || exit 1
- else
- cat $INDIR/$partfile >> $DEST || exit 1
- fi
-done < $HDR
-