Fixed #353 (paths relative to .lys file for rdb-file)

This fix also includes: L2N and LVS DB files are now also
included in the sessions.
This commit is contained in:
Matthias Koefferlein
2019-09-14 22:38:23 +02:00
parent 4ec4025e10
commit b747bbabd9
10 changed files with 2513 additions and 14 deletions
+46 -11
View File
@@ -30,7 +30,10 @@
#include "layStream.h"
#include "tlXMLParser.h"
#include "tlStream.h"
#include "tlFileUtils.h"
#include "tlUri.h"
#include "dbStream.h"
#include "dbLayoutToNetlist.h"
#include "rdb.h"
#include <fstream>
@@ -86,7 +89,16 @@ Session::fetch (const lay::MainWindow &mw)
const rdb::Database *rdb = view->get_rdb (j);
if (rdb && ! rdb->filename ().empty ()) {
view_desc.rdb_filenames.push_back (rdb->filename ());
view_desc.rdb_filenames.push_back (tl::InputStream::absolute_path (rdb->filename ()));
}
}
for (unsigned int j = 0; j < view->num_l2ndbs (); ++j) {
const db::LayoutToNetlist *l2ndb = view->get_l2ndb (j);
if (l2ndb && ! l2ndb->filename ().empty ()) {
view_desc.l2ndb_filenames.push_back (tl::InputStream::absolute_path (l2ndb->filename ()));
}
}
@@ -128,6 +140,17 @@ Session::fetch (const lay::MainWindow &mw)
}
std::string
Session::make_absolute (const std::string &fp) const
{
tl::URI fp_uri (fp);
if (! m_base_dir.empty () && ! tl::is_absolute (fp_uri.path ())) {
return tl::URI (m_base_dir).resolved (fp_uri).to_string ();
} else {
return fp;
}
}
void
Session::restore (lay::MainWindow &mw)
{
@@ -163,11 +186,7 @@ Session::restore (lay::MainWindow &mw)
std::map <std::string, const SessionLayoutDescriptor *>::const_iterator ld = ld_by_name.find (cvd->layout_name);
std::string fp = ld->second->file_path;
QFileInfo fi (tl::to_qstring (fp));
if (! m_base_dir.empty () && fi.isRelative ()) {
fp = tl::to_string (QDir (tl::to_qstring (m_base_dir)).filePath (tl::to_qstring (ld->second->file_path)));
}
std::string fp = make_absolute (ld->second->file_path);
bool ok = false;
if (ld != ld_by_name.end ()) {
@@ -218,13 +237,26 @@ Session::restore (lay::MainWindow &mw)
for (unsigned int j = 0; j < vd.rdb_filenames.size (); ++j) {
rdb::Database *rdb = new rdb::Database ();
std::auto_ptr<rdb::Database> rdb (new rdb::Database ());
try {
rdb->load (vd.rdb_filenames[j]);
view->add_rdb (rdb);
} catch (...) {
delete rdb;
rdb->load (make_absolute (vd.rdb_filenames[j]));
view->add_rdb (rdb.release ());
} catch (tl::Exception &ex) {
tl::error << ex.msg ();
} catch (...) {
}
}
for (unsigned int j = 0; j < vd.l2ndb_filenames.size (); ++j) {
try {
db::LayoutToNetlist *l2ndb = db::LayoutToNetlist::create_from_file (make_absolute (vd.l2ndb_filenames [j]));
view->add_l2ndb (l2ndb);
} catch (tl::Exception &ex) {
tl::error << ex.msg ();
} catch (...) {
}
}
@@ -289,6 +321,9 @@ session_structure ()
tl::make_element<std::vector<std::string>, SessionViewDescriptor> (&SessionViewDescriptor::rdb_filenames, "rdb-files",
tl::make_member<std::string, std::vector<std::string>::const_iterator, std::vector<std::string> > (&std::vector<std::string>::begin, &std::vector<std::string>::end, &std::vector<std::string>::push_back, "rdb-file")
) +
tl::make_element<std::vector<std::string>, SessionViewDescriptor> (&SessionViewDescriptor::l2ndb_filenames, "l2ndb-files",
tl::make_member<std::string, std::vector<std::string>::const_iterator, std::vector<std::string> > (&std::vector<std::string>::begin, &std::vector<std::string>::end, &std::vector<std::string>::push_back, "l2ndb-file")
) +
// for backward compatibility:
tl::make_element<lay::LayerPropertiesList, SessionViewDescriptor> (&SessionViewDescriptor::set_layer_properties, "layer-properties", lay::LayerPropertiesList::xml_format ()) +
tl::make_member<unsigned int, SessionViewDescriptor> (&SessionViewDescriptor::current_layer_list, "current-layer-property-tab") +
+3
View File
@@ -112,6 +112,7 @@ struct SessionViewDescriptor
std::vector<lay::LayerPropertiesList> layer_properties_lists;
unsigned int current_layer_list;
std::vector<std::string> rdb_filenames;
std::vector<std::string> l2ndb_filenames;
SessionCellViewDescriptors cellviews;
SessionAnnotationShapes annotation_shapes;
int active_cellview;
@@ -174,6 +175,8 @@ private:
std::string m_window_state;
std::string m_window_geometry;
std::string m_base_dir;
std::string make_absolute (const std::string &fp) const;
};
}
+171
View File
@@ -0,0 +1,171 @@
/*
KLayout Layout Viewer
Copyright (C) 2006-2019 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 "laySession.h"
#include "layMainWindow.h"
#include "layLayoutView.h"
#include "tlUnitTest.h"
#include "dbLayoutToNetlist.h"
#include "dbLayoutVsSchematic.h"
#include "rdb.h"
#include "antObject.h"
#include "antService.h"
#include "imgObject.h"
#include "imgService.h"
#include "tlFileUtils.h"
TEST (1)
{
lay::MainWindow *mw = lay::MainWindow::instance ();
tl_assert (mw != 0);
mw->close_all ();
mw->load_layout (tl::testsrc () + "/testdata/sessions/test.gds");
lay::LayoutView *view = mw->current_view ();
ant::Service *ant_service = view->get_plugin <ant::Service> ();
tl_assert (ant_service != 0);
if (ant_service) {
ant::Object ruler;
ruler.fmt ("Hello, world!");
ant_service->insert_ruler (ruler, false /*do not observe the ruler count limit*/);
}
img::Service *img_service = view->get_plugin <img::Service> ();
tl_assert (img_service != 0);
if (img_service) {
img::Object img;
img.load_data (tl::testsrc () + "/testdata/sessions/test.png");
img_service->insert_image (img);
}
std::auto_ptr<rdb::Database> rdb (new rdb::Database ());
rdb->load (tl::testsrc () + "/testdata/sessions/test.lyrdb");
view->add_rdb (rdb.release ());
std::auto_ptr<db::LayoutToNetlist> l2ndb (db::LayoutToNetlist::create_from_file (tl::testsrc () + "/testdata/sessions/test.l2n"));
view->add_l2ndb (l2ndb.release ());
std::auto_ptr<db::LayoutToNetlist> lvsdb (db::LayoutToNetlist::create_from_file (tl::testsrc () + "/testdata/sessions/test.lvsdb"));
view->add_l2ndb (lvsdb.release ());
std::string lys_file = tmp_file ("test1.lys");
mw->save_session (lys_file);
mw->close_all ();
EXPECT_EQ (mw->views (), (unsigned int) 0);
mw->restore_session (lys_file);
EXPECT_EQ (mw->views (), (unsigned int) 1);
view = mw->current_view ();
tl_assert (view != 0);
ant_service = view->get_plugin <ant::Service> ();
tl_assert (ant_service != 0);
if (ant_service) {
ant::AnnotationIterator a = ant_service->begin_annotations ();
EXPECT_EQ (a.at_end (), false);
if (! a.at_end ()) {
EXPECT_EQ (a->fmt (), "Hello, world!");
++a;
EXPECT_EQ (a.at_end (), true);
}
}
img_service = view->get_plugin <img::Service> ();
tl_assert (img_service != 0);
if (img_service) {
img::ImageIterator i = img_service->begin_images ();
EXPECT_EQ (i.at_end (), false);
if (! i.at_end ()) {
EXPECT_EQ (i->width (), (unsigned int) 256);
EXPECT_EQ (i->height (), (unsigned int) 256);
++i;
EXPECT_EQ (i.at_end (), true);
}
}
EXPECT_EQ (view->num_l2ndbs (), (unsigned int) 2);
EXPECT_EQ (tl::filename (view->get_l2ndb (0)->filename ()), "test.l2n");
EXPECT_EQ (tl::filename (view->get_l2ndb (1)->filename ()), "test.lvsdb");
EXPECT_EQ (dynamic_cast <db::LayoutVsSchematic *> (view->get_l2ndb (1)) != 0, true);
EXPECT_EQ (view->num_rdbs (), (unsigned int) 1);
EXPECT_EQ (tl::filename (view->get_rdb (0)->filename ()), "test.lyrdb");
}
// issue-353 (all paths relative to .lys file)
TEST (2)
{
lay::MainWindow *mw = lay::MainWindow::instance ();
tl_assert (mw != 0);
mw->close_all ();
mw->close_all ();
EXPECT_EQ (mw->views (), (unsigned int) 0);
mw->restore_session (tl::testsrc () + "/testdata/sessions/test_with_relative_paths.lys");
EXPECT_EQ (mw->views (), (unsigned int) 1);
lay::LayoutView *view = mw->current_view ();
tl_assert (view != 0);
ant::Service *ant_service = view->get_plugin <ant::Service> ();
tl_assert (ant_service != 0);
if (ant_service) {
ant::AnnotationIterator a = ant_service->begin_annotations ();
EXPECT_EQ (a.at_end (), false);
if (! a.at_end ()) {
EXPECT_EQ (a->fmt (), "Hello, world!");
++a;
EXPECT_EQ (a.at_end (), true);
}
}
img::Service *img_service = view->get_plugin <img::Service> ();
tl_assert (img_service != 0);
if (img_service) {
img::ImageIterator i = img_service->begin_images ();
EXPECT_EQ (i.at_end (), false);
if (! i.at_end ()) {
EXPECT_EQ (i->width (), (unsigned int) 256);
EXPECT_EQ (i->height (), (unsigned int) 256);
++i;
EXPECT_EQ (i.at_end (), true);
}
}
EXPECT_EQ (view->num_l2ndbs (), (unsigned int) 2);
EXPECT_EQ (tl::filename (view->get_l2ndb (0)->filename ()), "test.l2n");
EXPECT_EQ (tl::filename (view->get_l2ndb (1)->filename ()), "test.lvsdb");
EXPECT_EQ (dynamic_cast <db::LayoutVsSchematic *> (view->get_l2ndb (1)) != 0, true);
EXPECT_EQ (view->num_rdbs (), (unsigned int) 1);
EXPECT_EQ (tl::filename (view->get_rdb (0)->filename ()), "test.lyrdb");
}
+4 -3
View File
@@ -8,9 +8,10 @@ include($$PWD/../../lib_ut.pri)
SOURCES = \
laySalt.cc \
laySessionTests.cc
INCLUDEPATH += $$LAY_INC $$TL_INC $$LAYBASIC_INC $$DB_INC $$GSI_INC
DEPENDPATH += $$LAY_INC $$TL_INC $$LAYBASIC_INC $$DB_INC $$GSI_INC
INCLUDEPATH += $$LAY_INC $$TL_INC $$LAYBASIC_INC $$DB_INC $$GSI_INC $$ANT_INC $$IMG_INC $$RDB_INC
DEPENDPATH += $$LAY_INC $$TL_INC $$LAYBASIC_INC $$DB_INC $$GSI_INC $$ANT_INC $$IMG_INC $$RDB_INC
LIBS += -L$$DESTDIR_UT -lklayout_lay -lklayout_laybasic -lklayout_db -lklayout_tl -lklayout_gsi
LIBS += -L$$DESTDIR_UT -lklayout_lay -lklayout_laybasic -lklayout_db -lklayout_tl -lklayout_gsi -lklayout_ant -lklayout_img -lklayout_rdb