From 02f96f022af7895a4cb8be44a62e22d0356b79c5 Mon Sep 17 00:00:00 2001
From: Matthias Koefferlein
Date: Sat, 19 Dec 2020 16:37:58 +0100
Subject: [PATCH] WIP: added brackets for clarity in mapping expressions.
---
src/buddies/src/bd/bdReaderOptions.cc | 32 +++++++++++++++++--------
src/db/db/dbStreamLayers.cc | 30 ++++++++++++++++++++++-
src/db/unit_tests/dbStreamLayerTests.cc | 19 +++++++++++++++
src/lay/lay/doc/about/layer_mapping.xml | 25 +++++++++++++++++++
4 files changed, 95 insertions(+), 11 deletions(-)
diff --git a/src/buddies/src/bd/bdReaderOptions.cc b/src/buddies/src/bd/bdReaderOptions.cc
index 156e06048..6367fa374 100644
--- a/src/buddies/src/bd/bdReaderOptions.cc
+++ b/src/buddies/src/bd/bdReaderOptions.cc
@@ -155,32 +155,44 @@ GenericReaderOptions::add_options (tl::CommandLineOptions &cmd)
"layer is specified, all source layers addressed with the source specification are "
"combined into this target layer.\n"
"\n"
+ "For clarity, source and target specifications can be enclosed in round or square brackets. "
+ "With square brackets, the default target is '*/*' which results in the expansion of a source "
+ "layer range.\n"
+ "\n"
"To clone layers, add a mapping statement beginning with a '+' character. While other mapping statements "
"redefine mappings established before, mapping statement starting with '+' will clone the layer (1:m mapping).\n"
"\n"
- "It's also possible to cancel mappings established before by using an 'unmap' statement. Such a statement "
+ "You can cancel mappings established before by using an 'unmap' statement. Such a statement "
"begins with a '-' and lists the layers whose mapping is to be removed. This is useful for creating "
"'mapping holes' in sequences.\n"
"\n"
+ "If brackets are used, '+' (multi-mapping) and '-' (unmapping) needs to go before the brackets.\n"
+ "\n"
"Examples:\n"
"\n"
"* 1/0 2/0 3/0-255:17/0\n"
- " Selects 1/0, 2/0 and maps layer 3, datatype 0 to 255 to layer 17, datatype 0\n"
+ " Selects 1/0, 2/0 and maps layer 3, datatype 0 to 255 to layer 17, datatype 0.\n"
+ " If clarity, the mapping can also be written with brackets like this: '(1/0) (2/0) (3/0-255:17/0)'.\n"
"\n"
"* A:1/0 B:2/0\n"
- " Maps named layer A to 1/0 and named layer B to 2/0"
+ " Maps named layer A to 1/0 and named layer B to 2/0.\n"
+ " If clarity, the mapping can also be written with brackets like this: '(A:1/0) (B:2/0)'.\n"
"\n"
- "* */*:*/* +10/*:1000/*"
- " Includes all layers, but in addition copy all layers 10 to 1000 while keeping the datatype\n"
+ "* [*/*] +(10/*:1000)/*\n"
+ " Includes all layers, but in addition copies all datatypes of layer 10 to 1000 while keeping the datatype.\n"
+ " Note the square bracket which implies range expansion and how the brackets give a visual aid for the "
+ " grouping of the mapping parts.\n"
"\n"
- "* */*:*/* -10/*"
- " Includes all layers, but drops layer 10, all datatypes."
+ "* [*/*] -(10/*)\n"
+ " Includes all layers, but drops all datatypes from layer 10 through 'unmapping'.\n"
+ " Please note, that this specification requires -" + m_prefix + "s (skip unknown layers) because otherwise the "
+ " unmapped layers are still created through the unknown layer fallback path.\n"
)
<< tl::arg (group +
"--" + m_long_prefix + "layer-map-file=map", this, &GenericReaderOptions::set_layer_map_file, "Specifies the layer mapping for the input as a file",
- "This option specifies the layer selection or mapping like + -" + m_prefix + ", but takes the mapping for the given file. "
- "Each line in this file is read as one layer mapping expression. Empty lines or lines starting with a hash (#) character are "
- "ignored."
+ "This option specifies the layer selection or mapping like -" + m_prefix + "m, but takes the mapping from the given file. "
+ "Each line in this file is read as one layer mapping expression. "
+ "Empty lines or lines starting with a hash (#) character or with double slashes (//) are ignored."
)
;
}
diff --git a/src/db/db/dbStreamLayers.cc b/src/db/db/dbStreamLayers.cc
index ac2cc9819..52c14a679 100644
--- a/src/db/db/dbStreamLayers.cc
+++ b/src/db/db/dbStreamLayers.cc
@@ -635,6 +635,13 @@ LayerMap::mmap_expr (tl::Extractor &ex, unsigned int l)
{
try {
+ bool round_bracket = false, square_bracket = false;
+ if (ex.test ("(")) {
+ round_bracket = true;
+ } else if (ex.test ("[")) {
+ square_bracket = true;
+ }
+
do {
tl::Extractor ex_saved = ex;
@@ -678,7 +685,15 @@ LayerMap::mmap_expr (tl::Extractor &ex, unsigned int l)
LayerProperties lp;
lp.read (ex, true);
m_target_layers[l] = lp;
- }
+ } else if (square_bracket) {
+ m_target_layers[l] = LayerProperties (db::any_ld (), db::any_ld ());
+ }
+
+ if (round_bracket) {
+ ex.expect (")");
+ } else if (square_bracket) {
+ ex.expect ("]");
+ }
} catch (...) {
throw LayerSpecFormatException (ex.skip ());
@@ -790,6 +805,13 @@ LayerMap::unmap_expr (tl::Extractor &ex)
{
try {
+ bool round_bracket = false, square_bracket = false;
+ if (ex.test ("(")) {
+ round_bracket = true;
+ } else if (ex.test ("[")) {
+ square_bracket = true;
+ }
+
do {
tl::Extractor ex_saved = ex;
@@ -829,6 +851,12 @@ LayerMap::unmap_expr (tl::Extractor &ex)
lp.read (ex, true);
}
+ if (round_bracket) {
+ ex.expect (")");
+ } else if (square_bracket) {
+ ex.expect ("]");
+ }
+
} catch (...) {
throw LayerSpecFormatException (ex.skip ());
}
diff --git a/src/db/unit_tests/dbStreamLayerTests.cc b/src/db/unit_tests/dbStreamLayerTests.cc
index f031de1f3..81d6ab21a 100644
--- a/src/db/unit_tests/dbStreamLayerTests.cc
+++ b/src/db/unit_tests/dbStreamLayerTests.cc
@@ -74,6 +74,25 @@ TEST(1)
EXPECT_EQ (lm.first_logical (db::LDPair(10, 7)).first, false);
lm.map_expr ("'XP';10/7-8 : XN", 13);
EXPECT_EQ (lm.mapping_str (13), "10/7-8;XP : XN");
+
+ // brackets, "add_expr"
+ lm.clear ();
+ lm.add_expr ("[1-10/*]", 1);
+ EXPECT_EQ (lm.mapping_str (1), "1-10/* : */*");
+ lm.add_expr ("-(5/*)", 0);
+ EXPECT_EQ (lm.mapping_str (1), "1-4/*;6-10/* : */*");
+
+ lm.clear ();
+ lm.add_expr ("[1/15]", 1);
+ lm.add_expr ("+(1/5:1001/5)", 1);
+ // NOTE: the target is taken from the second expression (the last one wins)
+ EXPECT_EQ (lm.mapping_str (1), "1/5,15 : 1001/5");
+
+ lm.clear ();
+ lm.add_expr ("+(1/5:1001/5)", 1);
+ lm.add_expr ("[1/15]", 1);
+ // NOTE: the target is taken from the second expression (the last one wins)
+ EXPECT_EQ (lm.mapping_str (1), "1/5,15 : */*");
}
TEST(2)
diff --git a/src/lay/lay/doc/about/layer_mapping.xml b/src/lay/lay/doc/about/layer_mapping.xml
index 2f3ea4c82..4376bc1e5 100644
--- a/src/lay/lay/doc/about/layer_mapping.xml
+++ b/src/lay/lay/doc/about/layer_mapping.xml
@@ -201,5 +201,30 @@
when using unmapping and multi-mapping.
+ Brackets
+
+
+ Square brackets can be used to imply mapping to the original layer. When putting square brackets
+ around a mapping expression, the default target is "*/*", which means expansion to the original layer.
+ Hence the following statements are identical:
+
+
+ [1-10/*]
+1-10/* : */*
+
+
+
+ When combining this with "+" for multi-mapping, put "+" in front of the bracket.
+
+
+
+ You can put round brackets around mapping expressions for visual clarity, specifically when
+ combining them with "-" (unmapping) or "+" (multi-mapping):
+
+
+ -(1-10/*)
++(17/0 : 1017/0)
+
+