From 1f635015ce65b143741bde51e2c1b3ae3ef632cc Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Tue, 15 Dec 2020 23:05:34 +0100 Subject: [PATCH] WIP: backward compatible implementation of multi-map capability of layer mapping. --- src/db/db/dbGlyphs.cc | 12 +- src/db/db/dbLayoutQuery.cc | 2 +- src/db/db/dbNamedLayerReader.cc | 6 +- src/db/db/dbStreamLayers.cc | 84 ++++++++-- src/db/db/dbStreamLayers.h | 145 +++++++++++++++--- src/db/db/gsiDeclDbReader.cc | 86 ++++++++++- src/db/unit_tests/dbStreamLayerTests.cc | 126 +++++++++++---- src/lay/lay/laySearchReplaceDialog.cc | 2 +- .../streamers/dxf/db_plugin/dbDXFReader.cc | 2 +- .../gds2/db_plugin/dbGDS2ReaderBase.cc | 2 +- .../streamers/gds2/unit_tests/dbGDS2Reader.cc | 2 +- .../lefdef/db_plugin/dbLEFDEFImporter.cc | 6 +- .../oasis/db_plugin/dbOASISReader.cc | 2 +- 13 files changed, 393 insertions(+), 84 deletions(-) diff --git a/src/db/db/dbGlyphs.cc b/src/db/db/dbGlyphs.cc index ecea36e12..9cefc8b5e 100644 --- a/src/db/db/dbGlyphs.cc +++ b/src/db/db/dbGlyphs.cc @@ -174,9 +174,9 @@ TextGenerator::load_from_data (const char *data, size_t ndata, const std::string m_description = description; m_name = name; - std::pair l1 = map.logical (db::LDPair (1, 0)); - std::pair l2 = map.logical (db::LDPair (2, 0)); - std::pair l3 = map.logical (db::LDPair (3, 0)); + std::pair l1 = map.first_logical (db::LDPair (1, 0)); + std::pair l2 = map.first_logical (db::LDPair (2, 0)); + std::pair l3 = map.first_logical (db::LDPair (3, 0)); if (l1.first && l2.first) { read_from_layout (layout, l1.second, l2.second, l3.second); @@ -193,9 +193,9 @@ TextGenerator::load_from_file (const std::string &filename) m_description = filename; - std::pair l1 = map.logical (db::LDPair (1, 0)); - std::pair l2 = map.logical (db::LDPair (2, 0)); - std::pair l3 = map.logical (db::LDPair (3, 0)); + std::pair l1 = map.first_logical (db::LDPair (1, 0)); + std::pair l2 = map.first_logical (db::LDPair (2, 0)); + std::pair l3 = map.first_logical (db::LDPair (3, 0)); if (l1.first && l2.first) { read_from_layout (layout, l1.second, l2.second, l3.second); diff --git a/src/db/db/dbLayoutQuery.cc b/src/db/db/dbLayoutQuery.cc index 27ed3d8ad..3cf34a18e 100644 --- a/src/db/db/dbLayoutQuery.cc +++ b/src/db/db/dbLayoutQuery.cc @@ -228,7 +228,7 @@ public: { // get the layers which we have to look for for (db::Layout::layer_iterator l = layout->begin_layers (); l != layout->end_layers (); ++l) { - if (layers.is_empty () || layers.logical (*(*l).second).first) { + if (layers.is_empty () || layers.is_mapped (*(*l).second)) { m_layers.push_back ((*l).first); } } diff --git a/src/db/db/dbNamedLayerReader.cc b/src/db/db/dbNamedLayerReader.cc index 497fad153..adff2797f 100644 --- a/src/db/db/dbNamedLayerReader.cc +++ b/src/db/db/dbNamedLayerReader.cc @@ -128,7 +128,7 @@ NamedLayerReader::open_layer (db::Layout &layout, const std::string &n) std::pair ll (false, 0); - ll = m_layer_map.logical (n, layout); + ll = m_layer_map.first_logical (n, layout); if (! ll.first && !m_keep_layer_names) { if (extract_plain_layer (n.c_str (), l)) { @@ -136,7 +136,7 @@ NamedLayerReader::open_layer (db::Layout &layout, const std::string &n) db::LayerProperties lp; lp.layer = l; lp.datatype = 0; - ll = m_layer_map.logical (lp, layout); + ll = m_layer_map.first_logical (lp, layout); } else if (extract_ld (n.c_str (), l, d, on)) { @@ -144,7 +144,7 @@ NamedLayerReader::open_layer (db::Layout &layout, const std::string &n) lp.layer = l; lp.datatype = d; lp.name = on; - ll = m_layer_map.logical (lp, layout); + ll = m_layer_map.first_logical (lp, layout); } diff --git a/src/db/db/dbStreamLayers.cc b/src/db/db/dbStreamLayers.cc index f73d3dc11..e507ddea9 100644 --- a/src/db/db/dbStreamLayers.cc +++ b/src/db/db/dbStreamLayers.cc @@ -67,7 +67,7 @@ struct LmapEraseDatatypeInterval void operator() (LayerMap::datatype_map &a, const LayerMap::datatype_map &) { if (is_static_ld (m_dfrom) && is_static_ld (m_dto)) { - a.erase (m_dfrom, m_dto); + a.erase (m_dfrom, m_dto + 1); } else { a.clear (); } @@ -90,6 +90,40 @@ LayerMap::LayerMap () // .. nothing yet .. } +bool +LayerMap::is_mapped (const LDPair &p) const +{ + const datatype_map *dm = m_ld_map.mapped (p.layer); + if (!dm) { + return false; + } + const std::set *l = dm->mapped (p.datatype); + return (l && ! l->empty ()); +} + +bool +LayerMap::is_mapped (const std::string &n) const +{ + std::map >::const_iterator m = m_name_map.find (n); + return m != m_name_map.end () && ! m->second.empty (); +} + +bool +LayerMap::is_mapped (const db::LayerProperties &p) const +{ + std::set m; + if (p.layer >= 0 && p.datatype >= 0) { + if (is_mapped (db::LDPair (p.layer, p.datatype))) { + return true; + } + } + if (! p.name.empty ()) { + return is_mapped (p.name); + } else { + return false; + } +} + std::set LayerMap::logical (const LDPair &p) const { @@ -233,13 +267,19 @@ LayerMap::mapping_str (unsigned int ll) const { std::string s; bool f1 = true; + bool is_mmap = false; for (ld_map::const_iterator l = m_ld_map.begin (); l != m_ld_map.end (); ++l) { bool f2 = true; for (datatype_map::const_iterator d = l->second.begin (); d != l->second.end (); ++d) { + if (d->second.find (ll) != d->second.end ()) { + if (d->second.size () > 1) { + is_mmap = true; + } + // create a string representation if (!f2) { s += ","; @@ -268,6 +308,10 @@ LayerMap::mapping_str (unsigned int ll) const if (l->second.find (ll) != l->second.end ()) { + if (l->second.size () > 1) { + is_mmap = true; + } + if (!f1) { s += ";"; } @@ -285,7 +329,11 @@ LayerMap::mapping_str (unsigned int ll) const s += t->second.to_string (true); } - return s; + if (is_mmap) { + return "+" + s; + } else { + return s; + } } void @@ -439,19 +487,19 @@ LayerMap::mapping (unsigned int ll) const } void -LayerMap::map (const LDPair &p, unsigned int l) +LayerMap::mmap (const LDPair &p, unsigned int l) { insert (p, p, l, (const LayerProperties *) 0); } void -LayerMap::map (const std::string &name, unsigned int l) +LayerMap::mmap (const std::string &name, unsigned int l) { insert (name, l, (const LayerProperties *) 0); } void -LayerMap::map (const LayerProperties &f, unsigned int l) +LayerMap::mmap (const LayerProperties &f, unsigned int l) { if (f.name.empty () || is_static_ld (f.layer) || is_static_ld (f.datatype)) { map (db::LDPair (f.layer, f.datatype), l); @@ -462,19 +510,19 @@ LayerMap::map (const LayerProperties &f, unsigned int l) } void -LayerMap::map (const LDPair &p, unsigned int l, const LayerProperties &t) +LayerMap::mmap (const LDPair &p, unsigned int l, const LayerProperties &t) { insert (p, p, l, &t); } void -LayerMap::map (const std::string &name, unsigned int l, const LayerProperties &t) +LayerMap::mmap (const std::string &name, unsigned int l, const LayerProperties &t) { insert (name, l, &t); } void -LayerMap::map (const LayerProperties &f, unsigned int l, const LayerProperties &t) +LayerMap::mmap (const LayerProperties &f, unsigned int l, const LayerProperties &t) { if (f.name.empty () || is_static_ld (f.layer) || is_static_ld (f.datatype)) { map (db::LDPair (f.layer, f.datatype), l, t); @@ -485,13 +533,13 @@ LayerMap::map (const LayerProperties &f, unsigned int l, const LayerProperties & } void -LayerMap::map (const LDPair &p1, const LDPair &p2, unsigned int l) +LayerMap::mmap (const LDPair &p1, const LDPair &p2, unsigned int l) { insert (p1, p2, l, (const LayerProperties *) 0); } void -LayerMap::map (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties &lp) +LayerMap::mmap (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties &lp) { insert (p1, p2, l, &lp); } @@ -537,15 +585,15 @@ parse_intervals (tl::Extractor &ex, ld_interval_vector &v) } void -LayerMap::map_expr (const std::string &expr, unsigned int l) +LayerMap::mmap_expr (const std::string &expr, unsigned int l) { tl::Extractor ex (expr.c_str ()); - map_expr (ex, l); + mmap_expr (ex, l); ex.expect_end (); } void -LayerMap::map_expr (tl::Extractor &ex, unsigned int l) +LayerMap::mmap_expr (tl::Extractor &ex, unsigned int l) { try { @@ -684,7 +732,7 @@ LayerMap::unmap (const LDPair &p1, const LDPair &p2) LmapEraseDatatypeInterval op (p1.datatype, p2.datatype); if (db::is_static_ld (p1.layer) && db::is_static_ld (p2.layer)) { - m_ld_map.add (p1.layer, p1.layer + 1, LayerMap::datatype_map (), op); + m_ld_map.add (p1.layer, p2.layer + 1, LayerMap::datatype_map (), op); } else { m_ld_map.add (m_ld_map.begin ()->first.first, m_ld_map.end ()->first.second, LayerMap::datatype_map (), op); } @@ -812,7 +860,13 @@ LayerMap::from_string_file_format (const std::string &s) } else { if (! ex.at_end ()) { - lm.map_expr (ex, l); + if (ex.test ("+")) { + lm.mmap_expr (ex, l); + } else if (ex.test ("-")) { + lm.unmap_expr (ex); + } else { + lm.map_expr (ex, l); + } if (ex.test ("#") || ex.test ("//")) { // ignore comments } else { diff --git a/src/db/db/dbStreamLayers.h b/src/db/db/dbStreamLayers.h index 8ea0d78b5..26c15804a 100644 --- a/src/db/db/dbStreamLayers.h +++ b/src/db/db/dbStreamLayers.h @@ -199,7 +199,35 @@ public: */ LayerMap (); - /** + /** + * @brief Returns the first logical layer for a given layer specification + */ + template + std::pair first_logical (const L &p) const + { + std::set r = logical (p); + if (r.empty ()) { + return std::make_pair (false, 0); + } else { + return std::make_pair (true, *r.begin ()); + } + } + + /** + * @brief Returns the first logical layer for a given layer specification + */ + template + std::pair first_logical (const L &p, db::Layout &layout) const + { + std::set r = logical (p, layout); + if (r.empty ()) { + return std::make_pair (false, 0); + } else { + return std::make_pair (true, *r.begin ()); + } + } + + /** * @brief Query a layer mapping * * @return A pair telling if the layer is mapped (first=true) and @@ -246,6 +274,21 @@ public: */ std::set logical (const db::LDPair &p, db::Layout &layout) const; + /** + * @brief Returns a value indicating whether a layer (given by layer/datatype) is mapped + */ + bool is_mapped (const LDPair &p) const; + + /** + * @brief Returns a value indicating whether the given named layer is mapped + */ + bool is_mapped (const std::string &name) const; + + /** + * @brief Returns a value indicating whether a layer is mapped + */ + bool is_mapped (const db::LayerProperties &p) const; + /** * @brief Gets the target layer for a given logical layer * @@ -280,17 +323,81 @@ public: std::vector get_layers () const; /** - * @brief Map a ldpair to a logical layer + * @brief Single-map a physical to a logical layer + * + * "Single-mapping" substitutes a layer mapping. "Multimapping" (mmap_..) + * adds to a given mapping and allows generating 1:n mappings (m:n in fact). */ - void map (const LDPair &p, unsigned int l); + template + void map (const S &p, unsigned int l) + { + unmap (p); + mmap (p, l); + } /** - * @brief Map a name to a logical layer + * @brief Single-map a physical to a logical layer with a target layer */ - void map (const std::string &name, unsigned int l); + template + void map (const S &p, unsigned int l, const LayerProperties &t) + { + unmap (p); + mmap (p, l, t); + } /** - * @brief Map a name or LDPair to a logical layer + * @brief Single-map a physical layer interval with a target layer + */ + void map (const LDPair &p1, const LDPair &p2, unsigned int l) + { + unmap (p1, p2); + mmap (p1, p2, l); + } + + /** + * @brief Single-map a physical layer interval with a target layer + */ + void map (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties &t) + { + unmap (p1, p2); + mmap (p1, p2, l, t); + } + + /** + * @brief Single-map a physical layer interval (given by an expression) + */ + void map_expr (const std::string &expr, unsigned int l) + { + unmap_expr (expr); + mmap_expr (expr, l); + } + + /** + * @brief Same a map_expr with a string argument but taking the expression for a tl::Extractor + */ + void map_expr (tl::Extractor &ex, unsigned int l) + { + tl::Extractor ex1 = ex; + unmap_expr (ex1); + mmap_expr (ex, l); + } + + /** + * @brief Multi-map a ldpair to a logical layer + * + * "Multimapping" will not substitute but add to the mapping. + */ + void mmap (const LDPair &p, unsigned int l); + + /** + * @brief Multi-map a name to a logical layer + * + * "Multimapping" will not substitute but add to the mapping. + */ + void mmap (const std::string &name, unsigned int l); + + /** + * @brief Multi-map a name or LDPair to a logical layer * * The algorithm chooses the LDPair from the LayerProperties structure and/or * the name if no LDPair is given. If the source LayerProperties structure does @@ -299,26 +406,26 @@ public: * @param f The source (where to derive the match expression from) * @param l The logical layer to map to the match expression */ - void map (const LayerProperties &f, unsigned int l); + void mmap (const LayerProperties &f, unsigned int l); /** - * @brief Map a ldpair to a logical layer with a target layer + * @brief Multi-map a ldpair to a logical layer with a target layer * * The target layer specifies which layer to create for the * corresponding input. */ - void map (const LDPair &p, unsigned int l, const LayerProperties &t); + void mmap (const LDPair &p, unsigned int l, const LayerProperties &t); /** - * @brief Map a name to a logical layer with a target layer + * @brief Multi-map a name to a logical layer with a target layer * * The target layer specifies which layer to create for the * corresponding input. */ - void map (const std::string &name, unsigned int l, const LayerProperties &t); + void mmap (const std::string &name, unsigned int l, const LayerProperties &t); /** - * @brief Map a name or LDPair to a logical layer with a target layer + * @brief Multi-map a name or LDPair to a logical layer with a target layer * * The algorithm chooses the LDPair from the LayerProperties structure or * the name if no LDPair is given. If the source LayerProperties structure does @@ -328,23 +435,23 @@ public: * @param l The logical layer to map to the match expression * @param t The target layer to use for the mapped layer */ - void map (const LayerProperties &f, unsigned int l, const LayerProperties &t); + void mmap (const LayerProperties &f, unsigned int l, const LayerProperties &t); /** - * @brief Map a range of ldpair's to a logical layer + * @brief Multi-map a range of ldpair's to a logical layer * * The range is given by two pairs p1,p2. The layers * mapped are [p1.l,p2.l], the datatypes mapped are [p1.d,p2.d]. */ - void map (const LDPair &p1, const LDPair &p2, unsigned int l); + void mmap (const LDPair &p1, const LDPair &p2, unsigned int l); /** - * @brief Map a range of ldpair's to a logical layer with a target layer + * @brief Multi-map a range of ldpair's to a logical layer with a target layer * * The range is given by two pairs p1,p2. The layers * mapped are [p1.l,p2.l], the datatypes mapped are [p1.d,p2.d]. */ - void map (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties &t); + void mmap (const LDPair &p1, const LDPair &p2, unsigned int l, const LayerProperties &t); /** * @brief Map a range given by a string expression to a logical layer @@ -374,12 +481,12 @@ public: * This method will throw a LayerSpecFormatException if * something is wrong with the format string */ - void map_expr (const std::string &expr, unsigned int l); + void mmap_expr (const std::string &expr, unsigned int l); /** * @brief Same a map_expr with a string argument but taking the expression for a tl::Extractor */ - void map_expr (tl::Extractor &ex, unsigned int l); + void mmap_expr (tl::Extractor &ex, unsigned int l); /** * @brief Unmaps a LDPair diff --git a/src/db/db/gsiDeclDbReader.cc b/src/db/db/gsiDeclDbReader.cc index 16ab5bf71..19b82c6d3 100644 --- a/src/db/db/gsiDeclDbReader.cc +++ b/src/db/db/gsiDeclDbReader.cc @@ -36,7 +36,7 @@ namespace gsi static bool lm_is_mapped (const db::LayerMap *layer_map, const db::LayerProperties &lp) { - return !layer_map->logical (lp).empty (); + return layer_map->is_mapped (lp); } static int @@ -88,6 +88,36 @@ namespace gsi layer_map->map_expr (s, l); } + static void + lm_mmap (db::LayerMap *layer_map, const db::LayerProperties &lp, unsigned int l) + { + layer_map->mmap (lp, l); + } + + static void + lm_mmap_with_target (db::LayerMap *layer_map, const db::LayerProperties &lp, unsigned int l, const db::LayerProperties &t) + { + layer_map->mmap (lp, l, t); + } + + static void + lm_mmap_interval (db::LayerMap *layer_map, const db::LayerProperties &lp1, const db::LayerProperties &lp2, unsigned int l) + { + layer_map->mmap (ldpair_from_lp (lp1), ldpair_from_lp (lp2), l); + } + + static void + lm_mmap_interval_with_target (db::LayerMap *layer_map, const db::LayerProperties &lp1, const db::LayerProperties &lp2, unsigned int l, const db::LayerProperties &t) + { + layer_map->mmap (ldpair_from_lp (lp1), ldpair_from_lp (lp2), l, t); + } + + static void + lm_mmap_string (db::LayerMap *layer_map, std::string &s, unsigned int l) + { + layer_map->mmap_expr (s, l); + } + static void lm_unmap (db::LayerMap *layer_map, const db::LayerProperties &lp) { @@ -214,6 +244,51 @@ namespace gsi "\n" "Target mapping has been added in version 0.20.\n" ) + + gsi::method_ext ("mmap", &lm_mmap, gsi::arg ("phys_layer"), gsi::arg ("log_layer"), + "@brief Maps a physical layer to a logical one and adds to existing mappings\n" + "\n" + "This method acts like the corresponding 'map' method, but adds the logical layer to the receivers of the " + "given physical one. Hence this method implements 1:n mapping capabilities.\n" + "For backward compatibility, 'map' still substitutes mapping.\n" + "\n" + "Multi-mapping has been added in version 0.27.\n" + ) + + gsi::method_ext ("mmap", &lm_mmap_with_target, gsi::arg ("phys_layer"), gsi::arg ("log_layer"), gsi::arg ("target_layer"), + "@brief Maps a physical layer to a logical one, adds to existing mappings and specifies a target layer\n" + "\n" + "This method acts like the corresponding 'map' method, but adds the logical layer to the receivers of the " + "given physical one. Hence this method implements 1:n mapping capabilities.\n" + "For backward compatibility, 'map' still substitutes mapping.\n" + "\n" + "Multi-mapping has been added in version 0.27.\n" + ) + + gsi::method_ext ("mmap", &lm_mmap_interval, gsi::arg ("pl_start"), gsi::arg ("pl_stop"), gsi::arg ("log_layer"), + "@brief Maps a physical layer from the given interval to a logical one and adds to existing mappings\n" + "\n" + "This method acts like the corresponding 'map' method, but adds the logical layer to the receivers of the " + "given physical one. Hence this method implements 1:n mapping capabilities.\n" + "For backward compatibility, 'map' still substitutes mapping.\n" + "\n" + "Multi-mapping has been added in version 0.27.\n" + ) + + gsi::method_ext ("mmap", &lm_mmap_interval_with_target, gsi::arg ("pl_start"), gsi::arg ("pl_stop"), gsi::arg ("log_layer"), gsi::arg ("layer_properties"), + "@brief Maps a physical layer from the given interval to a logical one, adds to existing mappings and specifies a target layer\n" + "\n" + "This method acts like the corresponding 'map' method, but adds the logical layer to the receivers of the " + "given physical one. Hence this method implements 1:n mapping capabilities.\n" + "For backward compatibility, 'map' still substitutes mapping.\n" + "\n" + "Multi-mapping has been added in version 0.27.\n" + ) + + gsi::method_ext ("mmap", &lm_mmap_string, gsi::arg ("map_expr"), gsi::arg ("log_layer"), + "@brief Maps a physical layer given by an expression to a logical one and adds to existing mappings\n" + "\n" + "This method acts like the corresponding 'map' method, but adds the logical layer to the receivers of the " + "given physical one. Hence this method implements 1:n mapping capabilities.\n" + "For backward compatibility, 'map' still substitutes mapping.\n" + "\n" + "Multi-mapping has been added in version 0.27.\n" + ) + gsi::method_ext ("unmap", &lm_unmap, gsi::arg ("phys_layer"), "@brief Unmaps the given layer\n" "Unmapping will remove the specific layer from the mapping. This method allows generating " @@ -283,17 +358,18 @@ namespace gsi "ly.read(\"input.gds\", lo)\n" "@/code\n" "\n" - "1:n mapping is possible: a physical layer can be mapped to multiple logical layers. For this, mapping acts additive. " + "1:n mapping is supported: a physical layer can be mapped to multiple logical layers using 'mmap' instead of 'map'. When using this variant, " + "mapping acts additive.\n" "The following example will map layer 1, datatypes 0 to 255 to logical layer 0, and layer 1, datatype 17 to logical layers " "0 plus 1:" "\n" "@code" "lm = RBA::LayerMap::new\n" - "lm.map(\"1/0-255\", 0)\n" - "lm.map(\"1/17\", 1)\n" + "lm.map(\"1/0-255\", 0) # (can be 'mmap' too)\n" + "lm.mmap(\"1/17\", 1)\n" "@/code\n" "\n" - "'unmapping' allows to remove a mapping. This allows creating 'holes' in mapping ranges. The followin example maps " + "'unmapping' allows removing a mapping. This allows creating 'holes' in mapping ranges. The followin example maps " "layer 1, datatypes 0 to 16 and 18 to 255 to logical layer 0:" "\n" "@code" diff --git a/src/db/unit_tests/dbStreamLayerTests.cc b/src/db/unit_tests/dbStreamLayerTests.cc index b0ccf4f10..353e31693 100644 --- a/src/db/unit_tests/dbStreamLayerTests.cc +++ b/src/db/unit_tests/dbStreamLayerTests.cc @@ -29,14 +29,14 @@ TEST(1) db::LayerMap lm; lm.map (db::LDPair (1, 5), 17); - EXPECT_EQ (lm.logical (db::LDPair (1, 6)).first, false); - EXPECT_EQ (lm.logical (db::LDPair (1, 5)).first, true); - EXPECT_EQ (lm.logical (db::LDPair (1, 5)).second, (unsigned int) 17); + EXPECT_EQ (lm.first_logical (db::LDPair (1, 6)).first, false); + EXPECT_EQ (lm.first_logical (db::LDPair (1, 5)).first, true); + EXPECT_EQ (lm.first_logical (db::LDPair (1, 5)).second, (unsigned int) 17); lm.map (db::LDPair (1, 0), db::LDPair (5,0), 18); - EXPECT_EQ (lm.logical (db::LDPair (2, 0)).first, true); - EXPECT_EQ (lm.logical (db::LDPair (2, 0)).second, (unsigned int) 18); - EXPECT_EQ (lm.logical (db::LDPair (0, 0)).first, false); + EXPECT_EQ (lm.first_logical (db::LDPair (2, 0)).first, true); + EXPECT_EQ (lm.first_logical (db::LDPair (2, 0)).second, (unsigned int) 18); + EXPECT_EQ (lm.first_logical (db::LDPair (0, 0)).first, false); EXPECT_EQ (lm.mapping_str (18), "1/0;2-5/0"); EXPECT_EQ (lm.mapping_str (17), "1/5"); @@ -62,16 +62,16 @@ TEST(1) lm.map_expr ("XP;10/7-8 : XN", 13); EXPECT_EQ (lm.mapping_str (13), "10/7-8;XP : XN"); - EXPECT_EQ (lm.logical ("XP").second, (unsigned int) 13); - EXPECT_EQ (lm.logical ("XP").first, true); - EXPECT_EQ (lm.logical (db::LDPair(10, 6)).first, false); - EXPECT_EQ (lm.logical (db::LDPair(10, 7)).first, true); - EXPECT_EQ (lm.logical (db::LDPair(10, 7)).second, (unsigned int) 13); + EXPECT_EQ (lm.first_logical ("XP").second, (unsigned int) 13); + EXPECT_EQ (lm.first_logical ("XP").first, true); + EXPECT_EQ (lm.first_logical (db::LDPair(10, 6)).first, false); + EXPECT_EQ (lm.first_logical (db::LDPair(10, 7)).first, true); + EXPECT_EQ (lm.first_logical (db::LDPair(10, 7)).second, (unsigned int) 13); EXPECT_EQ (lm.mapping (13).to_string (), "XN (10/7)"); lm.clear (); - EXPECT_EQ (lm.logical (db::LDPair(10, 7)).first, false); + 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"); } @@ -349,55 +349,55 @@ TEST(6) EXPECT_EQ (layers_to_string (ly), "1/0,3/10"); std::pair p; - p = lm.logical (db::LayerProperties (1, 0)); + p = lm.first_logical (db::LayerProperties (1, 0)); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 0); - p = lm.logical (db::LayerProperties (2, 0)); + p = lm.first_logical (db::LayerProperties (2, 0)); EXPECT_EQ (p.first, false); - p = lm.logical (db::LayerProperties (3, 0)); + p = lm.first_logical (db::LayerProperties (3, 0)); EXPECT_EQ (p.first, false); - p = lm.logical (db::LayerProperties (3, 10)); + p = lm.first_logical (db::LayerProperties (3, 10)); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 1); - p = lm.logical (db::LayerProperties (3, 99)); + p = lm.first_logical (db::LayerProperties (3, 99)); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 1); EXPECT_EQ (layers_to_string (ly), "1/0,3/10"); // this will create layer 2/0 in the layout - p = lm.logical (db::LayerProperties (2, 0), ly); + p = lm.first_logical (db::LayerProperties (2, 0), ly); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 2); EXPECT_EQ (layers_to_string (ly), "1/0,3/10,2/0"); - p = lm.logical (db::LayerProperties (2, 0)); + p = lm.first_logical (db::LayerProperties (2, 0)); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 2); - p = lm.logical (db::LayerProperties (2, 0), ly); + p = lm.first_logical (db::LayerProperties (2, 0), ly); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 2); EXPECT_EQ (layers_to_string (ly), "1/0,3/10,2/0"); // this will create layer 2/42 in the layout - p = lm.logical (db::LayerProperties (2, 42), ly); + p = lm.first_logical (db::LayerProperties (2, 42), ly); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 3); EXPECT_EQ (layers_to_string (ly), "1/0,3/10,2/0,2/42"); - p = lm.logical (db::LayerProperties (2, 42)); + p = lm.first_logical (db::LayerProperties (2, 42)); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 3); - p = lm.logical (db::LayerProperties (2, 42), ly); + p = lm.first_logical (db::LayerProperties (2, 42), ly); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 3); @@ -429,19 +429,91 @@ TEST(7) EXPECT_EQ (layers_to_string (ly), "85/0,185/0,,"); std::pair p; - p = lm.logical (db::LayerProperties (85, 0)); + p = lm.first_logical (db::LayerProperties (85, 0)); EXPECT_EQ (p.first, false); EXPECT_EQ (p.second, (unsigned int) 0); - p = lm.logical (db::LayerProperties (185, 0)); + p = lm.first_logical (db::LayerProperties (185, 0)); EXPECT_EQ (p.first, false); EXPECT_EQ (p.second, (unsigned int) 0); - p = lm.logical (db::LayerProperties (10000, 0)); + p = lm.first_logical (db::LayerProperties (10000, 0)); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 1); - p = lm.logical (db::LayerProperties (10001, 0)); + p = lm.first_logical (db::LayerProperties (10001, 0)); EXPECT_EQ (p.first, true); EXPECT_EQ (p.second, (unsigned int) 0); } + +// multi-mapping, unmapping +TEST(8) +{ + db::LayerMap lm; + + unsigned int n = 0; + + // refinement + // all + lm.mmap_expr ("*/*", n++); + EXPECT_EQ (lm.mapping_str (0), "*/*"); + EXPECT_EQ (lm.to_string (), + "layer_map('*/*')" + ); + EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ()); + + // some + lm.mmap_expr ("*/1-10", n++); + EXPECT_EQ (lm.to_string (), + "layer_map('+*/0,1-10,11-*';'+*/1-10')" + ); + EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ()); + + // others + lm.mmap_expr ("*/5,15", n++); + + EXPECT_EQ (lm.to_string (), + "layer_map('+*/0,1-4,5,6-10,11-14,15,16-*';'+*/1-4,5,6-10';'+*/5,15')" + ); + EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ()); + + // NOTE: the leading "+" indicates that the listed layers may go somewhere else, so we can't plainly map them + EXPECT_EQ (lm.mapping_str (0), "+*/0,1-4,5,6-10,11-14,15,16-*"); + EXPECT_EQ (lm.mapping_str (1), "+*/1-4,5,6-10"); + EXPECT_EQ (lm.mapping_str (2), "+*/5,15"); + EXPECT_EQ (lm.mapping_str (3), ""); + + lm = db::LayerMap (); + n = 0; + + // refinement + // all + lm.mmap_expr ("*/*", n++); + EXPECT_EQ (lm.mapping_str (0), "*/*"); + EXPECT_EQ (lm.to_string (), + "layer_map('*/*')" + ); + EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ()); + + // some + lm.mmap_expr ("1-10/*", n++); + EXPECT_EQ (lm.to_string (), + "layer_map('+0/*;1-10/*;11-*/*';'+1-10/*')" + ); + EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ()); + + // others + lm.mmap_expr ("5,15/*", n++); + + EXPECT_EQ (lm.to_string (), + "layer_map('+0/*;1-4/*;5/*;6-10/*;11-14/*;15/*;16-*/*';'+1-4/*;5/*;6-10/*';'+5/*;15/*')" + ); + EXPECT_EQ (db::LayerMap::from_string_file_format (lm.to_string_file_format ()).to_string (), lm.to_string ()); + + // NOTE: the leading "+" indicates that the listed layers may go somewhere else, so we can't plainly map them + EXPECT_EQ (lm.mapping_str (0), "+0/*;1-4/*;5/*;6-10/*;11-14/*;15/*;16-*/*"); + EXPECT_EQ (lm.mapping_str (1), "+1-4/*;5/*;6-10/*"); + EXPECT_EQ (lm.mapping_str (2), "+5/*;15/*"); + EXPECT_EQ (lm.mapping_str (3), ""); +} + diff --git a/src/lay/lay/laySearchReplaceDialog.cc b/src/lay/lay/laySearchReplaceDialog.cc index 41b591104..e9ef8b94f 100644 --- a/src/lay/lay/laySearchReplaceDialog.cc +++ b/src/lay/lay/laySearchReplaceDialog.cc @@ -504,7 +504,7 @@ SearchReplaceResults::export_layout (db::Layout &layout) std::map::const_iterator lm = m_lp_map.find (layer); if (lm != m_lp_map.end ()) { - std::pair ll = insert_lm.logical (lm->second); + std::pair ll = insert_lm.first_logical (lm->second); if (! ll.first) { layer = layout.insert_layer (lm->second); insert_lm.map (lm->second, layer, lm->second); diff --git a/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc b/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc index cb023d887..5517001d8 100644 --- a/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc +++ b/src/plugins/streamers/dxf/db_plugin/dbDXFReader.cc @@ -381,7 +381,7 @@ DXFReader::do_read (db::Layout &layout, db::cell_index_type top) { // create the zero layer - this is not mapped to GDS but can be specified in the layer mapping as // a layer named "0". - std::pair ll = layer_map ().logical (zero_layer_name, layout); + std::pair ll = layer_map ().first_logical (zero_layer_name, layout); if (ll.first) { // create the layer if it is not part of the layout yet. diff --git a/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc b/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc index d79793638..7111089d9 100644 --- a/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc +++ b/src/plugins/streamers/gds2/db_plugin/dbGDS2ReaderBase.cc @@ -184,7 +184,7 @@ GDS2ReaderBase::finish_element (db::PropertiesRepository &rep) std::pair GDS2ReaderBase::open_dl (db::Layout &layout, const LDPair &dl, bool create) { - std::pair ll = m_layer_map.logical (dl, layout); + std::pair ll = m_layer_map.first_logical (dl, layout); if (ll.first) { return ll; diff --git a/src/plugins/streamers/gds2/unit_tests/dbGDS2Reader.cc b/src/plugins/streamers/gds2/unit_tests/dbGDS2Reader.cc index 838260bf3..7361c67a2 100644 --- a/src/plugins/streamers/gds2/unit_tests/dbGDS2Reader.cc +++ b/src/plugins/streamers/gds2/unit_tests/dbGDS2Reader.cc @@ -332,7 +332,7 @@ TEST(2) db::Layout layout_piece (&m); layout_piece = layout; - std::pair jj = map_full.logical (pairs[i]); + std::pair jj = map_full.first_logical (pairs[i]); EXPECT_EQ (jj.first, true); for (unsigned int j = 0; j < layout_piece.layers(); ++j) { diff --git a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc index 2c47e2984..f68700609 100644 --- a/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc +++ b/src/plugins/streamers/lefdef/db_plugin/dbLEFDEFImporter.cc @@ -1180,7 +1180,7 @@ LEFDEFReaderState::open_layer_uncached (db::Layout &layout, const std::string &n } // employ the layer map to find the target layer - std::pair ll = m_layer_map.logical (lp, layout); + std::pair ll = m_layer_map.first_logical (lp, layout); if (ll.first) { @@ -1300,10 +1300,10 @@ LEFDEFReaderState::open_layer_uncached (db::Layout &layout, const std::string &n // Route the layer through the layer map, first the decorated name and if there is no mapping, the // undecorated one. - std::pair ll = m_layer_map.logical (name, layout); + std::pair ll = m_layer_map.first_logical (name, layout); bool generic_match = false; if (! ll.first) { - ll = m_layer_map.logical (n, layout); + ll = m_layer_map.first_logical (n, layout); generic_match = true; } else if (n == name) { // no suffix defined in tech component -> treat as generic match and combine datatypes diff --git a/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc b/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc index 3bf5485a5..131fb3e9a 100644 --- a/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc +++ b/src/plugins/streamers/oasis/db_plugin/dbOASISReader.cc @@ -557,7 +557,7 @@ OASISReader::warn (const std::string &msg) std::pair OASISReader::open_dl (db::Layout &layout, const LDPair &dl, bool create) { - std::pair ll = m_layer_map.logical (dl, layout); + std::pair ll = m_layer_map.first_logical (dl, layout); if (ll.first) { return ll;