klayout/src/unit_tests/layParsedLayerSource.cc

605 lines
20 KiB
C++

/*
KLayout Layout Viewer
Copyright (C) 2006-2017 Matthias Koefferlein
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 St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "layParsedLayerSource.h"
#include "dbLayout.h"
#include "dbCell.h"
#include "utHead.h"
TEST (1)
{
lay::ParsedLayerSource ps1 (1, 2, -1);
EXPECT_EQ (ps1.to_string (), "1/2@*");
lay::ParsedLayerSource ps2 (5, 0, 0);
EXPECT_EQ (ps2.to_string (), "5/0@1");
EXPECT_EQ (ps2.has_name (), false);
lay::ParsedLayerSource ps3 ("aname", 1);
EXPECT_EQ (ps3.to_string (), "aname@2");
EXPECT_EQ (ps3.has_name (), true);
lay::ParsedLayerSource ps4 ("bname", -1);
EXPECT_EQ (ps4.to_string (), "bname@*");
EXPECT_EQ (ps1 < ps2, true);
EXPECT_EQ (ps2 < ps2, false);
EXPECT_EQ (ps2 < ps1, false);
EXPECT_EQ (ps2 < ps3, true);
EXPECT_EQ (ps3 < ps4, false);
EXPECT_EQ (ps4 < ps3, true);
EXPECT_EQ (ps1 == ps2, false);
EXPECT_EQ (ps2 == ps3, false);
EXPECT_EQ (ps3 == ps4, false);
EXPECT_EQ (ps4 == lay::ParsedLayerSource ("x", -1), false);
EXPECT_EQ (ps4 == lay::ParsedLayerSource ("bname", -1), true);
EXPECT_EQ (ps3 == lay::ParsedLayerSource ("aname", 1), true);
EXPECT_EQ (ps2 == lay::ParsedLayerSource (5, 0, 0), true);
EXPECT_EQ (ps4 != lay::ParsedLayerSource ("x", -1), true);
EXPECT_EQ (ps4 != lay::ParsedLayerSource ("bname", -1), false);
EXPECT_EQ (ps1 == lay::ParsedLayerSource (ps1.to_string ()), true);
EXPECT_EQ (ps2 == lay::ParsedLayerSource (ps2.to_string ()), true);
EXPECT_EQ (ps3 == lay::ParsedLayerSource (ps3.to_string ()), true);
EXPECT_EQ (ps4 == lay::ParsedLayerSource (ps4.to_string ()), true);
ps1 = ps2;
lay::ParsedLayerSource psc = ps2;
EXPECT_EQ (ps1 == ps2, true);
EXPECT_EQ (ps2 == psc, true);
EXPECT_EQ (lay::ParsedLayerSource ("4/0@*") == lay::ParsedLayerSource (4, 0, -1), true);
}
TEST (2)
{
lay::ParsedLayerSource ps1 ("@2");
EXPECT_EQ (ps1.to_string (), "*/*@2");
lay::ParsedLayerSource ps2 ("5");
EXPECT_EQ (ps2.to_string (), "5/0@1");
lay::ParsedLayerSource ps3 ("/5");
EXPECT_EQ (ps3.to_string (), "*/5@1");
lay::ParsedLayerSource ps4 ("name@5");
EXPECT_EQ (ps4.to_string (), "name@5");
lay::ParsedLayerSource ps5 ("name");
EXPECT_EQ (ps5.to_string (), "name@1");
lay::ParsedLayerSource ps6 ("%5");
EXPECT_EQ (ps6.to_string (), "%5@1");
lay::ParsedLayerSource ps7 ("1/5%4@7");
EXPECT_EQ (ps7.to_string (), "%4@7");
}
TEST (3)
{
lay::ParsedLayerSource ps1 ("@2");
ps1 += lay::ParsedLayerSource ("1");
EXPECT_EQ (ps1.to_string (), "1/0@2");
lay::ParsedLayerSource ps2 ("@2");
ps2 += lay::ParsedLayerSource ("@3");
EXPECT_EQ (ps2.to_string (), "*/*@2");
lay::ParsedLayerSource ps3 ("1/5@*");
ps3 += lay::ParsedLayerSource ("@3");
EXPECT_EQ (ps3.to_string (), "1/5@3");
lay::ParsedLayerSource ps4 ("namea");
EXPECT_EQ (ps4.has_name (), true);
ps4 += lay::ParsedLayerSource ("nameb");
EXPECT_EQ (ps4.has_name (), true);
EXPECT_EQ (ps4.to_string (), "namea@1");
lay::ParsedLayerSource ps5 ("namea@5");
ps5 += lay::ParsedLayerSource ("1/*");
EXPECT_EQ (ps5.to_string (), "namea 1/*@5");
lay::ParsedLayerSource ps6 ("1/5@4");
EXPECT_EQ (ps6.has_name (), false);
ps6 += lay::ParsedLayerSource ("nameb");
EXPECT_EQ (ps6.has_name (), true);
EXPECT_EQ (ps6.to_string (), "nameb 1/5@4");
lay::ParsedLayerSource ps7 ("*/5");
EXPECT_EQ (ps7.has_name (), false);
ps7 += lay::ParsedLayerSource ("2/7");
EXPECT_EQ (ps7.has_name (), false);
EXPECT_EQ (ps7.to_string (), "2/5@1");
lay::ParsedLayerSource ps8 ("1/*@1");
ps8 += lay::ParsedLayerSource ("*/8@2");
EXPECT_EQ (ps8.to_string (), "1/8@1");
lay::ParsedLayerSource ps9;
EXPECT_EQ (ps9.to_string (), "*/*@*");
EXPECT_EQ (ps9.has_name (), false);
ps9.layer (2);
EXPECT_EQ (ps9.to_string (), "2/*@*");
EXPECT_EQ (ps9.has_name (), false);
ps9.datatype (3);
EXPECT_EQ (ps9.to_string (), "2/3@*");
EXPECT_EQ (ps9.has_name (), false);
ps9.name ("abc");
EXPECT_EQ (ps9.to_string (), "abc 2/3@*");
EXPECT_EQ (ps9.has_name (), true);
ps9.name (std::string ());
EXPECT_EQ (ps9.to_string (), "2/3@*");
EXPECT_EQ (ps9.has_name (), false);
}
TEST (4)
{
lay::ParsedLayerSource ps1 ("@2");
EXPECT_EQ (ps1.to_string (), "*/*@2");
lay::ParsedLayerSource ps2 ("@2 (*0.5 -1.0,17.1 m45)");
EXPECT_EQ (ps2.to_string (), "*/*@2 (m45 *0.5 -1,17.1)");
}
TEST (5)
{
lay::ParsedLayerSource ps0 ("@2");
lay::ParsedLayerSource ps1 ("@2 [ X == #2 ]");
EXPECT_EQ (ps1.to_string (), "*/*@2 ['X'==#2]");
lay::ParsedLayerSource ps2 ("[X==#2||X==Y&&Z!=##4] @2");
EXPECT_EQ (ps2.to_string (), "*/*@2 [('X'==#2||'X'=='Y')&&'Z'!=##4]");
lay::ParsedLayerSource ps2a ("[!(X==#2||X==Y&&Z!=##4)] @2");
EXPECT_EQ (ps2a.to_string (), "*/*@2 [!(('X'==#2||'X'=='Y')&&'Z'!=##4)]");
lay::ParsedLayerSource ps2b ("[(X!=#2&&X!=Y)||Z==##4] @2");
EXPECT_EQ (ps2b.to_string (), "*/*@2 [('X'!=#2&&'X'!='Y')||'Z'==##4]");
lay::ParsedLayerSource ps3 ("[!(X==#2||(X==Y&&Y==X)&&!Z!=##4)] @2");
EXPECT_EQ (ps3.to_string (), "*/*@2 [!(('X'==#2||('X'=='Y'&&'Y'=='X'))&&!('Z'!=##4))]");
lay::ParsedLayerSource ps4 ("@2 [X==#2||X==#3||X==#20||X==#120||X==#210||X==#5||X==#15||X==#11||X==#17||X==#18]");
EXPECT_EQ (ps4.to_string (), "*/*@2 ['X'==#2||'X'==#3||'X'==#20||'X'==#120||'X'==#210||'X'==#5||'X'==#15||'X'==#11||'X'==#17||'X'==#18]");
EXPECT_EQ (ps4.display_string (0), "@2 ['X'==#2||'X'==#3||'X'==#20||'X'==#120||...]");
lay::ParsedLayerSource ps4a;
ps4a = ps4;
EXPECT_EQ (ps4a.to_string (), ps4.to_string ());
EXPECT_EQ (ps4a == ps4, true);
lay::ParsedLayerSource ps4b (ps4);
EXPECT_EQ (ps4b.to_string (), ps4.to_string ());
lay::ParsedLayerSource ps4c ("@2 [X==#3||X==#20||X==#120||X==#210||X==#5||X==#15||X==#11||X==#17||X==#18]");
EXPECT_EQ (ps4c == ps4, false);
EXPECT_EQ (ps4c < ps4, true);
EXPECT_EQ (ps4 < ps4c, false);
lay::ParsedLayerSource ps4d ("@2 [X==#2||X==#4||X==#20||X==#120||X==#210||X==#5||X==#15||X==#11||X==#17||X==#18]");
EXPECT_EQ (ps4d == ps4, false);
EXPECT_EQ (ps4d < ps4, false);
EXPECT_EQ (ps4 < ps4d, true);
lay::ParsedLayerSource ps4e ("@2 [X==##2||X==#3||X==#20||X==#120||X==#210||X==#5||X==#15||X==#11||X==#17||X==#18]");
EXPECT_EQ (ps4e == ps4, true);
EXPECT_EQ (ps4e < ps4, false);
EXPECT_EQ (ps4 < ps4e, false);
lay::ParsedLayerSource ps4f ("@2 [X==#222||X==#3||X==#4||X==#20||X==#120||X==#210||X==#5||X==#15||X==#11||X==#17||X==#18]");
EXPECT_EQ (ps4f == ps4, false);
EXPECT_EQ (ps4f < ps4, false);
EXPECT_EQ (ps4 < ps4f, true);
lay::ParsedLayerSource ps4g ("@2 [X!=#2||X==#3||X==#20||X==#120||X==#210||X==#5||X==#15||X==#11||X==#17||X==#18]");
EXPECT_EQ (ps4g == ps4, false);
EXPECT_EQ (ps4g < ps4, false);
EXPECT_EQ (ps4 < ps4g, true);
db::PropertiesRepository::properties_set ps;
db::PropertiesRepository rep;
std::set<db::properties_id_type> ids;
bool inv;
ps.insert (std::make_pair (rep.prop_name_id (tl::Variant ("X")), tl::Variant (2l)));
db::properties_id_type id1 = rep.properties_id (ps);
EXPECT_EQ (ps1.property_selector ().check (rep, id1), true);
EXPECT_EQ (ps0.property_selector ().check (rep, id1), true);
ids.clear ();
inv = ps1.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, false);
EXPECT_EQ (ids.size (), 1);
EXPECT_EQ (*ids.begin (), id1);
ids.clear ();
inv = ps0.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, true);
EXPECT_EQ (ids.size (), 0);
ps.clear ();
ps.insert (std::make_pair (rep.prop_name_id (tl::Variant ("X")), tl::Variant (3l)));
db::properties_id_type id2 = rep.properties_id (ps);
EXPECT_EQ (ps1.property_selector ().check (rep, id2), false);
EXPECT_EQ (ps0.property_selector ().check (rep, id2), true);
ids.clear ();
inv = ps1.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, false);
EXPECT_EQ (ids.size (), 1);
EXPECT_EQ (*ids.begin () == id2, false);
EXPECT_EQ (*ids.begin (), id1);
ids.clear ();
inv = ps0.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, true);
EXPECT_EQ (ids.size (), 0);
ps.clear ();
ps.insert (std::make_pair (rep.prop_name_id (tl::Variant ("X")), tl::Variant (2l)));
ps.insert (std::make_pair (rep.prop_name_id (tl::Variant ("Z")), tl::Variant (4.0)));
db::properties_id_type id3 = rep.properties_id (ps);
EXPECT_EQ (ps2.property_selector ().check (rep, id3), false);
EXPECT_EQ (ps0.property_selector ().check (rep, id3), true);
ids.clear ();
inv = ps2.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, false);
EXPECT_EQ (ids.size (), 1);
EXPECT_EQ (*ids.begin () == id3, false);
EXPECT_EQ (*ids.begin (), id1);
ids.clear ();
inv = ps0.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, true);
EXPECT_EQ (ids.size (), 0);
ps.clear ();
ps.insert (std::make_pair (rep.prop_name_id (tl::Variant ("X")), tl::Variant (2l)));
ps.insert (std::make_pair (rep.prop_name_id (tl::Variant ("Z")), tl::Variant (6l)));
db::properties_id_type id4 = rep.properties_id (ps);
EXPECT_EQ (ps2.property_selector ().check (rep, id4), true);
ids.clear ();
inv = ps2.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, false);
EXPECT_EQ (ids.size (), 2);
EXPECT_EQ (*ids.begin (), id1);
EXPECT_EQ (*(++ids.begin ()), id4);
ps.clear ();
ps.insert (std::make_pair (rep.prop_name_id (tl::Variant ("X")), tl::Variant (2l)));
ps.insert (std::make_pair (rep.prop_name_id (tl::Variant ("Z")), tl::Variant (5.0)));
db::properties_id_type id5 = rep.properties_id (ps);
EXPECT_EQ (ps2.property_selector ().check (rep, id5), true);
ids.clear ();
inv = ps2.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, false);
EXPECT_EQ (ids.size (), 3);
EXPECT_EQ (*ids.begin (), id1);
EXPECT_EQ (*(++ids.begin ()), id4);
EXPECT_EQ (*(++(++ids.begin ())), id5);
EXPECT_EQ (ps2a.property_selector ().check (rep, id5), false);
ids.clear ();
inv = ps2a.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, true);
EXPECT_EQ (ids.size (), 3);
EXPECT_EQ (*ids.begin (), id1);
EXPECT_EQ (*(++ids.begin ()), id4);
EXPECT_EQ (*(++(++ids.begin ())), id5);
EXPECT_EQ (ps2b.property_selector ().check (rep, id5), false);
ids.clear ();
inv = ps2b.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, true);
EXPECT_EQ (ids.size (), 3);
EXPECT_EQ (*ids.begin (), id1);
EXPECT_EQ (*(++ids.begin ()), id4);
EXPECT_EQ (*(++(++ids.begin ())), id5);
ps.clear ();
db::properties_id_type id6 = rep.properties_id (ps);
EXPECT_EQ (ps2.property_selector ().check (rep, id6), false);
ids.clear ();
inv = ps2.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, false);
EXPECT_EQ (ids.size (), 3);
EXPECT_EQ (*ids.begin (), id1);
EXPECT_EQ (*(++ids.begin ()), id4);
EXPECT_EQ (*(++(++ids.begin ())), id5);
EXPECT_EQ (ps0.property_selector ().check (rep, id6), true);
ids.clear ();
inv = ps0.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, true);
EXPECT_EQ (ids.size (), 0);
ps.insert (std::make_pair (rep.prop_name_id (tl::Variant ("Z")), tl::Variant (5l)));
db::properties_id_type id7 = rep.properties_id (ps);
EXPECT_EQ (ps4.property_selector ().check (rep, id7), false);
ids.clear ();
inv = ps4.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, false);
EXPECT_EQ (ids.size (), 5);
EXPECT_EQ (ids.find (id7) == ids.end (), true);
ps.insert (std::make_pair (rep.prop_name_id (tl::Variant ("X")), tl::Variant (15l)));
db::properties_id_type id8 = rep.properties_id (ps);
EXPECT_EQ (ps4.property_selector ().check (rep, id8), true);
ids.clear ();
inv = ps4.property_selector ().matching (rep, ids);
EXPECT_EQ (inv, false);
EXPECT_EQ (ids.size (), 6);
EXPECT_EQ (ids.find (id8) != ids.end (), true);
}
TEST (6)
{
lay::ParsedLayerSource ps1;
ps1 = lay::ParsedLayerSource ("");
EXPECT_EQ (ps1.to_string (), "*/*@1");
ps1 = lay::ParsedLayerSource ("#1");
EXPECT_EQ (ps1.to_string (), "*/*@1 #0..1");
ps1 = lay::ParsedLayerSource ("#1..4");
EXPECT_EQ (ps1.to_string (), "*/*@1 #1..4");
EXPECT_EQ (ps1 == lay::ParsedLayerSource ("#1..4"), true);
EXPECT_EQ (ps1 != lay::ParsedLayerSource ("#1..4"), false);
EXPECT_EQ (ps1 == lay::ParsedLayerSource ("#1..5"), false);
EXPECT_EQ (ps1 != lay::ParsedLayerSource ("#1..5"), true);
ps1 = lay::ParsedLayerSource ("#1..2");
EXPECT_EQ (ps1.to_string (), "*/*@1 #1..2");
ps1 = lay::ParsedLayerSource (" # .. 2");
EXPECT_EQ (ps1.to_string (), "*/*@1 #..2");
ps1 = lay::ParsedLayerSource (" # 1 .. ");
EXPECT_EQ (ps1.to_string (), "*/*@1 #1..");
ps1 = lay::ParsedLayerSource ();
ps1 += lay::ParsedLayerSource ("#..20");
EXPECT_EQ (ps1.to_string (), "*/*@1 #..20");
ps1 += lay::ParsedLayerSource ("#10..11");
EXPECT_EQ (ps1.to_string (), "*/*@1 #10..20");
ps1 = lay::ParsedLayerSource ();
ps1 += lay::ParsedLayerSource ("#5..");
EXPECT_EQ (ps1.to_string (), "*/*@1 #5..");
ps1 += lay::ParsedLayerSource ("#10..11");
EXPECT_EQ (ps1.to_string (), "*/*@1 #5..11");
ps1 = lay::ParsedLayerSource ("#*");
EXPECT_EQ (ps1.to_string (), "*/*@1 #0..*");
ps1 = lay::ParsedLayerSource ("#..*");
EXPECT_EQ (ps1.to_string (), "*/*@1 #..*");
ps1 = lay::ParsedLayerSource ("#..(*)");
EXPECT_EQ (ps1.to_string (), "*/*@1 #..*");
ps1 = lay::ParsedLayerSource ("#1..*");
EXPECT_EQ (ps1.to_string (), "*/*@1 #1..*");
ps1 = lay::ParsedLayerSource ("#1..(*)");
EXPECT_EQ (ps1.to_string (), "*/*@1 #1..*");
ps1 = lay::ParsedLayerSource ("#(*)");
EXPECT_EQ (ps1.to_string (), "*/*@1 #(0)..*");
ps1 = lay::ParsedLayerSource ("#(-1)..(5)");
EXPECT_EQ (ps1.to_string (), "*/*@1 #(-1)..(5)");
ps1 = lay::ParsedLayerSource ("#(2)");
EXPECT_EQ (ps1.to_string (), "*/*@1 #(0)..(2)");
ps1 = lay::ParsedLayerSource ("#(2)..3");
EXPECT_EQ (ps1.to_string (), "*/*@1 #(2)..3");
ps1 = lay::ParsedLayerSource ("#2..(3)");
EXPECT_EQ (ps1.to_string (), "*/*@1 #2..(3)");
ps1 = lay::ParsedLayerSource ("#>2..(<3)");
EXPECT_EQ (ps1.to_string (), "*/*@1 #>2..(<3)");
ps1 = lay::ParsedLayerSource ("#>2..(<*)");
EXPECT_EQ (ps1.to_string (), "*/*@1 #>2..<*");
}
TEST (7)
{
lay::ParsedLayerSource ps1;
ps1 = lay::ParsedLayerSource ("(*2)");
EXPECT_EQ (ps1.to_string (), "*/*@1 (r0 *2 0,0)");
ps1 = lay::ParsedLayerSource ("(*2) (*1.5)");
EXPECT_EQ (ps1.to_string (), "*/*@1 (r0 *2 0,0) (r0 *1.5 0,0)");
lay::ParsedLayerSource ps2 (ps1);
ps1 += lay::ParsedLayerSource ("(*2)");
EXPECT_EQ (ps1.to_string (), "*/*@1 (r0 *4 0,0) (r0 *3 0,0)");
ps1 = ps2;
ps1 += lay::ParsedLayerSource ("(*2) (*3)");
EXPECT_EQ (ps1.to_string (), "*/*@1 (r0 *4 0,0) (r0 *6 0,0) (r0 *3 0,0) (r0 *4.5 0,0)");
}
TEST (8)
{
lay::ParsedLayerSource ps1;
ps1 = lay::ParsedLayerSource ("(*2) {-* +HALLO}");
EXPECT_EQ (ps1.to_string (), "*/*@1 {-* +HALLO} (r0 *2 0,0)");
ps1 = lay::ParsedLayerSource ("{-HALLO} (*2) (*1.5)");
EXPECT_EQ (ps1.to_string (), "*/*@1 {-HALLO} (r0 *2 0,0) (r0 *1.5 0,0)");
}
TEST (10)
{
lay::CellSelector sel;
tl::Extractor ex;
ex = tl::Extractor ("+HALLO * -H*");
sel.parse (ex);
EXPECT_EQ (sel.to_string (), "+HALLO +* -H*");
ex = tl::Extractor ("+HALLO * -H*}ignored");
sel.parse (ex);
EXPECT_EQ (sel.to_string (), "+HALLO +* -H*");
EXPECT_EQ (ex.test ("}"), true);
ex = tl::Extractor ("+HALLO (* -H*)");
sel.parse (ex);
EXPECT_EQ (sel.to_string (), "+HALLO (+* -H*)");
ex = tl::Extractor ("( +HALLO -H* ) ( *HA 'WITH BLANK' )");
sel.parse (ex);
EXPECT_EQ (sel.to_string (), "(+HALLO -H*) (+*HA +'WITH BLANK')");
std::string c = sel.to_string ();
ex = tl::Extractor (c.c_str ());
sel = lay::CellSelector ();
sel.parse (ex);
EXPECT_EQ (sel.to_string (), "(+HALLO -H*) (+*HA +'WITH BLANK')");
lay::CellSelector sel2;
EXPECT_EQ (sel2.to_string (), "");
EXPECT_EQ (sel2.is_empty (), true);
EXPECT_EQ (sel == sel2, false);
EXPECT_EQ (sel != sel2, true);
EXPECT_EQ (sel < sel2, false);
EXPECT_EQ (sel2 < sel, true);
sel2 = sel;
EXPECT_EQ (sel2.to_string (), "(+HALLO -H*) (+*HA +'WITH BLANK')");
EXPECT_EQ (sel2.is_empty (), false);
EXPECT_EQ (sel == sel2, true);
EXPECT_EQ (sel != sel2, false);
EXPECT_EQ (sel < sel2, false);
EXPECT_EQ (sel2 < sel, false);
lay::CellSelector sel2a (sel2);
EXPECT_EQ (sel2a.to_string (), "(+HALLO -H*) (+*HA +'WITH BLANK')");
}
lay::CellSelector selector_from_string (const char *s)
{
tl::Extractor ex (s);
lay::CellSelector sel;
sel.parse (ex);
return sel;
}
std::string tspath (const db::Layout &l, db::cell_index_type c, lay::PartialTreeSelector &pt)
{
std::string r;
if (pt.is_selected ()) {
r += "+";
} else {
r += "-";
}
r += l.cell_name (c);
bool any = false;
for (db::Cell::child_cell_iterator cc = l.cell (c).begin_child_cells (); ! cc.at_end (); ++cc) {
int cs = pt.is_child_selected (*cc);
if (cs) {
if (! any) {
r += "(";
any = true;
}
pt.descend (*cc);
r += tspath (l, *cc, pt);
pt.ascend ();
}
}
if (any) {
r += ")";
}
return r;
}
TEST (11)
{
db::Layout layout;
db::Cell &c1 = layout.cell (layout.add_cell ("C1"));
db::Cell &c2 = layout.cell (layout.add_cell ("C2"));
db::Cell &c3 = layout.cell (layout.add_cell ("C3"));
db::Cell &c4 = layout.cell (layout.add_cell ("C4"));
db::Cell &c5 = layout.cell (layout.add_cell ("C5"));
db::Cell &cc1 = layout.cell (layout.add_cell ("CC1"));
db::Cell &cc2 = layout.cell (layout.add_cell ("CC2"));
db::Cell &cc3 = layout.cell (layout.add_cell ("CC3"));
db::Cell &cc4 = layout.cell (layout.add_cell ("CC4"));
c1.insert (db::CellInstArray (c2.cell_index (), db::Trans ()));
c2.insert (db::CellInstArray (c3.cell_index (), db::Trans ()));
c2.insert (db::CellInstArray (c4.cell_index (), db::Trans ()));
c2.insert (db::CellInstArray (cc2.cell_index (), db::Trans ()));
c4.insert (db::CellInstArray (cc4.cell_index (), db::Trans ()));
c3.insert (db::CellInstArray (cc3.cell_index (), db::Trans ()));
c3.insert (db::CellInstArray (c5.cell_index (), db::Trans ()));
c1.insert (db::CellInstArray (cc1.cell_index (), db::Trans ()));
lay::PartialTreeSelector pt (selector_from_string("").create_tree_selector (layout, c1.cell_index ()));
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "+C1(+C2(+C3(+C5+CC3)+C4(+CC4)+CC2)+CC1)");
pt = selector_from_string("+C1").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "+C1(+C2(+C3(+C5+CC3)+C4(+CC4)+CC2)+CC1)");
pt = selector_from_string("-C1").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "-C1");
pt = selector_from_string("-C2").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "+C1(+CC1)");
pt = selector_from_string("+C1 -C2").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "+C1(+CC1)");
pt = selector_from_string("+C1 ( -C* +CC* )").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "+C1(+CC1)");
pt = selector_from_string("-C2 +C3").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "+C1(-C2(+C3(+C5+CC3)-C4(-CC4)-CC2)+CC1)");
pt = selector_from_string("-C2 +CC*").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "+C1(-C2(-C3(-C5+CC3)-C4(+CC4)+CC2)+CC1)");
pt = selector_from_string("+CC*").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "-C1(-C2(-C3(-C5+CC3)-C4(+CC4)+CC2)+CC1)");
pt = selector_from_string("-* +CC*").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "-C1(-C2(-C3(-C5+CC3)-C4(+CC4)+CC2)+CC1)");
pt = selector_from_string("-* ( -* +CC* )").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "-C1(+CC1)");
pt = selector_from_string("-C3 +CC*").create_tree_selector (layout, c1.cell_index ());
EXPECT_EQ (tspath (layout, c1.cell_index (), pt), "+C1(+C2(-C3(-C5+CC3)+C4(+CC4)+CC2)+CC1)");
}