From c6ede46fd004ef47a1670e053d4f2b3b3c3854f1 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 30 Nov 2019 00:09:44 +0100 Subject: [PATCH] WIP: substantial changes - force lower-case layer names to allow CIF/MAG loop (CIF needs upper-case layer names, MAG doesn't) - reverted CIF reader to standard - new options for writer: tech, "zero timestamp". - file name MUST be consistent with one cell name. Reason: it's not possible to derive the initial cell from the given options, so without the file name being consistent, we can't know what to write there. Basically the file name rather supplies the path. --- src/db/db/dbNamedLayerReader.cc | 4 +- src/laybasic/laybasic/layCellView.cc | 14 ++ .../streamers/cif/db_plugin/dbCIFReader.cc | 7 - .../streamers/cif/db_plugin/dbCIFWriter.cc | 6 +- .../streamers/magic/db_plugin/dbMAG.cc | 4 +- .../streamers/magic/db_plugin/dbMAGFormat.h | 17 +- .../streamers/magic/db_plugin/dbMAGReader.cc | 12 +- .../streamers/magic/db_plugin/dbMAGWriter.cc | 159 ++++++------------ .../streamers/magic/db_plugin/dbMAGWriter.h | 8 +- .../streamers/magic/db_plugin/gsiDeclDbMAG.cc | 44 ++++- .../magic/lay_plugin/MAGWriterOptionPage.ui | 40 ++++- .../magic/lay_plugin/layMAGWriterPlugin.cc | 4 + .../streamers/magic/unit_tests/dbMAGReader.cc | 12 +- src/tl/tl/tlTimer.h | 2 +- .../{mag_test.mag.gz => MAG_TEST.mag.gz} | Bin testdata/magic/mag_test_au.cif.gz | Bin 443 -> 443 bytes 16 files changed, 180 insertions(+), 153 deletions(-) rename testdata/magic/{mag_test.mag.gz => MAG_TEST.mag.gz} (100%) diff --git a/src/db/db/dbNamedLayerReader.cc b/src/db/db/dbNamedLayerReader.cc index 43975c685..2bc9c7a1f 100644 --- a/src/db/db/dbNamedLayerReader.cc +++ b/src/db/db/dbNamedLayerReader.cc @@ -84,7 +84,7 @@ extract_ld (const char *s, int &l, int &d, std::string &n) { l = d = 0; - if (*s == 'L') { + if (*s == 'L' || *s == 'l') { ++s; } @@ -97,7 +97,7 @@ extract_ld (const char *s, int &l, int &d, std::string &n) ++s; } - if (*s == 'D' || *s == '.') { + if (*s == 'D' || *s == 'd' || *s == '.') { ++s; if (! safe_isdigit (*s)) { return false; diff --git a/src/laybasic/laybasic/layCellView.cc b/src/laybasic/laybasic/layCellView.cc index 6c44e29de..d91f78bc8 100644 --- a/src/laybasic/laybasic/layCellView.cc +++ b/src/laybasic/laybasic/layCellView.cc @@ -339,6 +339,14 @@ LayoutHandle::load (const db::LoadLayoutOptions &options, const std::string &tec db::Reader reader (stream); db::LayerMap new_lmap = reader.read (layout (), m_load_options); + // If there is no technology given and the reader reports one, use this one + if (technology.empty ()) { + std::string tech_from_reader = layout ().meta_info_value ("technology"); + if (! tech_from_reader.empty ()) { + set_tech_name (tech_from_reader); + } + } + // Update the file's data: file_watcher ().remove_file (filename ()); file_watcher ().add_file (filename ()); @@ -358,6 +366,12 @@ LayoutHandle::load () db::Reader reader (stream); db::LayerMap new_lmap = reader.read (layout (), m_load_options); + // Attach the technology from the reader if it reports one + std::string tech_from_reader = layout ().meta_info_value ("technology"); + if (! tech_from_reader.empty ()) { + set_tech_name (tech_from_reader); + } + // Update the file's data: file_watcher ().remove_file (filename ()); file_watcher ().add_file (filename ()); diff --git a/src/plugins/streamers/cif/db_plugin/dbCIFReader.cc b/src/plugins/streamers/cif/db_plugin/dbCIFReader.cc index 1a9cb5ccd..af7e88467 100644 --- a/src/plugins/streamers/cif/db_plugin/dbCIFReader.cc +++ b/src/plugins/streamers/cif/db_plugin/dbCIFReader.cc @@ -106,17 +106,10 @@ CIFReader::warn (const std::string &msg) void CIFReader::skip_blanks() { - bool had_space = false; while (! m_stream.at_end ()) { char c = m_stream.peek_char (); if (isupper (c) || isdigit (c) || c == '-' || c == '(' || c == ')' || c == ';') { return; - } else if (isspace (c)) { - had_space = true; - } else if (had_space) { - // an extension to allow lower-case cell and layer names and some more flexibility - // in general: after space (blank, tab ...) any character will end the sequence. - return; } m_stream.get_char (); } diff --git a/src/plugins/streamers/cif/db_plugin/dbCIFWriter.cc b/src/plugins/streamers/cif/db_plugin/dbCIFWriter.cc index 7af28cd01..34fc1ee56 100644 --- a/src/plugins/streamers/cif/db_plugin/dbCIFWriter.cc +++ b/src/plugins/streamers/cif/db_plugin/dbCIFWriter.cc @@ -135,7 +135,7 @@ CIFWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa double sf = 1.0; *this << "DS " << cell_index << " " << tl_scale_denom << " " << tl_scale_divider << ";" << m_endl; - *this << "9 " << tl::to_word_or_quoted_string (layout.cell_name (*cell)) << ";" << m_endl; + *this << "9 " << tl::to_word_or_quoted_string (tl::to_upper_case (layout.cell_name (*cell))) << ";" << m_endl; // instances for (db::Cell::const_iterator inst = cref.begin (); ! inst.at_end (); ++inst) { @@ -250,7 +250,7 @@ CIFWriter::emit_layer() { if (m_needs_emit) { m_needs_emit = false; - *this << "L " << tl::to_word_or_quoted_string(m_layer.name, "0123456789_.$") << ";" << m_endl; + *this << "L " << tl::to_word_or_quoted_string (tl::to_upper_case (m_layer.name), "0123456789_.$") << ";" << m_endl; } } @@ -264,7 +264,7 @@ CIFWriter::write_texts (const db::Layout &layout, const db::Cell &cell, unsigned emit_layer (); - *this << "94 " << tl::to_word_or_quoted_string(shape->text_string(), "0123456789:<>/&%$!.-_#+*?\\[]{}"); + *this << "94 " << tl::to_word_or_quoted_string (shape->text_string(), "0123456789:<>/&%$!.-_#+*?\\[]{}"); double h = shape->text_size () * layout.dbu (); diff --git a/src/plugins/streamers/magic/db_plugin/dbMAG.cc b/src/plugins/streamers/magic/db_plugin/dbMAG.cc index 76cb45985..546d8d2e0 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAG.cc +++ b/src/plugins/streamers/magic/db_plugin/dbMAG.cc @@ -99,7 +99,9 @@ public: virtual tl::XMLElementBase *xml_writer_options_element () const { return new db::WriterOptionsXMLElement ("mag", - tl::make_member (&db::MAGWriterOptions::lambda, "lambda") + tl::make_member (&db::MAGWriterOptions::lambda, "lambda") + + tl::make_member (&db::MAGWriterOptions::tech, "tech") + + tl::make_member (&db::MAGWriterOptions::write_timestamp, "write-timestamp") ); } }; diff --git a/src/plugins/streamers/magic/db_plugin/dbMAGFormat.h b/src/plugins/streamers/magic/db_plugin/dbMAGFormat.h index 4a3cea896..e0cc80f47 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAGFormat.h +++ b/src/plugins/streamers/magic/db_plugin/dbMAGFormat.h @@ -146,7 +146,7 @@ public: * @brief The constructor */ MAGWriterOptions () - : lambda (0.0) + : lambda (0.0), write_timestamp (true) { // .. nothing yet .. } @@ -160,6 +160,21 @@ public: */ double lambda; + /** + * @brief Specifies the technology value for writing Magic files + * + * If this value is set an empty string, the technology store in the layout's + * "technology" meta data is used. + */ + std::string tech; + + /** + * @brief A value indicating whether the real (true) or fake (false) timestamp is written + * + * A fake, static timestamp is useful for comparing files. + */ + bool write_timestamp; + /** * @brief Implementation of FormatSpecificWriterOptions */ diff --git a/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc b/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc index f83cad191..713aae052 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc +++ b/src/plugins/streamers/magic/db_plugin/dbMAGReader.cc @@ -142,7 +142,7 @@ MAGReader::cell_from_path (const std::string &path, db::Layout &layout) return c->second; } -// @@@ this can lead to cell variants if a cell is present with different library paths ... (L500_CHAR_p) + // NOTE: this can lead to cell variants if a cell is present with different library paths ... (L500_CHAR_p) db::cell_index_type ci = layout.add_cell (cell_name_from_path (path).c_str ()); m_cells_read.insert (std::make_pair (path, ci)); @@ -219,11 +219,7 @@ bool MAGReader::resolve_path (const std::string &path, std::string &real_path) { tl::Eval expr; -/* @@@ - expr.set_var ("tech_dir", m_default_base_path); - expr.set_var ("tech_file", m_lyt_file); - expr.set_var ("tech_name", m_lyt_file); -*/ + // TODO: more variables? expr.set_var ("tech_info", m_tech); tl::URI path_uri (path); @@ -305,7 +301,7 @@ MAGReader::do_read_part (db::Layout &layout, db::cell_index_type cell_index, tl: if (&m_stream == &stream) { // initial file - store technology - layout.add_meta_info (db::MetaInfo ("magic_tech", "MAGIC technology string", m_tech)); + layout.add_meta_info (db::MetaInfo ("technology", "MAGIC technology string", m_tech)); } ex.expect_end (); @@ -316,7 +312,7 @@ MAGReader::do_read_part (db::Layout &layout, db::cell_index_type cell_index, tl: ex.read (ts); if (&m_stream == &stream) { - // initial file - store technology + // initial file - store timestamp layout.add_meta_info (db::MetaInfo ("magic_timestamp", "MAGIC main file timestamp", tl::to_string (ts))); } diff --git a/src/plugins/streamers/magic/db_plugin/dbMAGWriter.cc b/src/plugins/streamers/magic/db_plugin/dbMAGWriter.cc index f8f763064..c75a0c8bd 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAGWriter.cc +++ b/src/plugins/streamers/magic/db_plugin/dbMAGWriter.cc @@ -30,6 +30,7 @@ #include "tlUri.h" #include "tlLog.h" #include "tlUniqueName.h" +#include "tlTimer.h" #include #include @@ -52,6 +53,23 @@ MAGWriter::MAGWriter () void MAGWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLayoutOptions &options) { + std::vector > layers; + options.get_valid_layers (layout, layers, db::SaveLayoutOptions::LP_AssignName); + + std::set cell_set; + options.get_cells (layout, cell_set, layers); + + tl::URI src (stream.path ()); + std::string basename = tl::basename (src.path ()); + std::pair ci = layout.cell_by_name (basename.c_str ()); + if (! ci.first) { + throw tl::Exception (tl::to_string (tr ("Magic file names must be valid cell names. This is not a valid name: ")) + basename); + } + + if (cell_set.find (ci.second) == cell_set.end ()) { + throw tl::Exception (tl::to_string (tr ("Cell name derived from file name isn't a selected cell: ")) + basename); + } + m_options = options.get_options (); mp_stream = &stream; @@ -59,10 +77,12 @@ MAGWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa m_ext = tl::extension (m_base_uri.path ()); m_base_uri.set_path (tl::dirname (m_base_uri.path ())); - m_cells_written.clear (); - m_cells_to_write.clear (); - m_layer_names.clear (); - m_timestamp = 0; // @@@ set timestamp? + m_timestamp = 0; + if (m_options.write_timestamp) { + timespec ts; + tl::current_utc_time (&ts); + m_timestamp = ts.tv_sec; + } double lambda = m_options.lambda; if (lambda <= 0.0) { @@ -75,87 +95,10 @@ MAGWriter::write (db::Layout &layout, tl::OutputStream &stream, const db::SaveLa m_sf = layout.dbu () / lambda; - if (layout.end_top_cells () - layout.begin_top_down () == 1) { - - // write the one top cell to the given stream. Otherwise - write_cell (*layout.begin_top_down (), layout, stream); - - } else { - - stream << "# KLayout is not writing this file as there are multiple top cells - see those files for the individual cells."; - - for (db::Layout::top_down_const_iterator c = layout.begin_top_down (); c != layout.end_top_cells (); ++c) { - m_cells_to_write.insert (std::make_pair (*c, filename_for_cell (*c, layout))); - } - + for (std::set::const_iterator c = cell_set.begin (); c != cell_set.end (); ++c) { + tl::OutputStream os (filename_for_cell (*c, layout), tl::OutputStream::OM_Auto, true); + write_cell (*c, layers, layout, os); } - - while (! m_cells_to_write.empty ()) { - - std::map cells_to_write; - cells_to_write.swap (m_cells_to_write); - - for (std::map::const_iterator cw = cells_to_write.begin (); cw != cells_to_write.end (); ++cw) { - tl::OutputStream os (cw->second, tl::OutputStream::OM_Auto, true); - write_cell (cw->first, layout, os); - } - - } -} - -std::string -MAGWriter::layer_name (unsigned int li, const Layout &layout) -{ - std::map::const_iterator i = m_layer_names.find (li); - if (i != m_layer_names.end ()) { - return i->second; - } - - // Avoid built-in names, like "end", "space", "labels" and "checkpaint" - std::set used_names; - used_names.insert ("end"); - used_names.insert ("space"); - used_names.insert ("labels"); - used_names.insert ("checkpaint"); - - if (m_layer_names.empty ()) { - - for (db::Layout::layer_iterator i = layout.begin_layers (); i != layout.end_layers (); ++i) { - - db::LayerProperties lp = layout.get_properties ((*i).first); - if (! lp.name.empty ()) { - - std::string lp_name = lp.name; - lp_name = tl::unique_name (lp_name, used_names, "_"); - used_names.insert (lp_name); - - m_layer_names.insert (std::make_pair ((*i).first, lp_name)); - - } - - } - - for (db::Layout::layer_iterator i = layout.begin_layers (); i != layout.end_layers (); ++i) { - - db::LayerProperties lp = layout.get_properties ((*i).first); - if (lp.name.empty ()) { - - std::string ld_name = std::string ("L") + tl::to_string (lp.layer); - if (lp.datatype) { - ld_name += "D"; - ld_name += tl::to_string (lp.datatype); - } - - ld_name = tl::unique_name (ld_name, used_names, "_"); - used_names.insert (ld_name); - m_layer_names.insert (std::make_pair ((*i).first, ld_name)); - - } - } - - } - - return m_layer_names [li]; } std::string @@ -171,24 +114,29 @@ MAGWriter::filename_for_cell (db::cell_index_type ci, db::Layout &layout) } void -MAGWriter::write_cell (db::cell_index_type ci, db::Layout &layout, tl::OutputStream &os) +MAGWriter::write_cell (db::cell_index_type ci, const std::vector > &layers, db::Layout &layout, tl::OutputStream &os) { m_cellname = layout.cell_name (ci); try { - do_write_cell (ci, layout, os); + do_write_cell (ci, layers, layout, os); } catch (tl::Exception &ex) { throw tl::Exception (ex.msg () + tl::to_string (tr (" when writing cell ")) + m_cellname); } } void -MAGWriter::do_write_cell (db::cell_index_type ci, db::Layout &layout, tl::OutputStream &os) +MAGWriter::do_write_cell (db::cell_index_type ci, const std::vector > &layers, db::Layout &layout, tl::OutputStream &os) { os.set_as_text (true); os << "magic\n"; - // @@@ write tech - os << "tech scmos\n"; + std::string tech = m_options.tech; + if (tech.empty ()) { + tech = layout.meta_info_value ("technology"); + } + if (! tech.empty ()) { + os << "tech " << tl::to_word_or_quoted_string (tl::to_lower_case (tech)) << "\n"; + } os << "timestamp " << m_timestamp << "\n"; @@ -197,39 +145,36 @@ MAGWriter::do_write_cell (db::cell_index_type ci, db::Layout &layout, tl::Output os << "<< checkpaint >>\n"; write_polygon (db::Polygon (cell.bbox ()), layout, os); - for (db::Layout::layer_iterator i = layout.begin_layers (); i != layout.end_layers (); ++i) { + bool any; - unsigned int li = (*i).first; - if (! cell.shapes (li).empty ()) { - os << "<< " << tl::to_word_or_quoted_string (layer_name (li, layout)) << " >>\n"; - for (db::Shapes::shape_iterator s = cell.shapes (li).begin (db::ShapeIterator::Boxes | db::ShapeIterator::Polygons | db::ShapeIterator::Paths); ! s.at_end (); ++s) { - db::Polygon poly; - s->polygon (poly); - write_polygon (poly, layout, os); + for (std::vector >::const_iterator ll = layers.begin (); ll != layers.end (); ++ll) { + any = false; + for (db::Shapes::shape_iterator s = cell.shapes (ll->first).begin (db::ShapeIterator::Boxes | db::ShapeIterator::Polygons | db::ShapeIterator::Paths); ! s.at_end (); ++s) { + if (! any) { + os << "<< " << tl::to_word_or_quoted_string (tl::to_lower_case (ll->second.name)) << " >>\n"; + any = true; } + db::Polygon poly; + s->polygon (poly); + write_polygon (poly, layout, os); } - } - bool any = false; - - for (db::Layout::layer_iterator i = layout.begin_layers (); i != layout.end_layers (); ++i) { - for (db::Shapes::shape_iterator s = cell.shapes ((*i).first).begin (db::ShapeIterator::Texts); ! s.at_end (); ++s) { + any = false; + for (std::vector >::const_iterator ll = layers.begin (); ll != layers.end (); ++ll) { + for (db::Shapes::shape_iterator s = cell.shapes (ll->first).begin (db::ShapeIterator::Texts); ! s.at_end (); ++s) { if (! any) { os << "<< labels >>\n"; + any = true; } db::Text text; s->text (text); - write_label (layer_name ((*i).first, layout), text, layout, os); + write_label (tl::to_lower_case (ll->second.name), text, layout, os); } } m_cell_id.clear (); for (db::Cell::const_iterator i = cell.begin (); ! i.at_end (); ++i) { - if (m_cells_written.find (i->cell_index ()) == m_cells_written.end ()) { - m_cells_written.insert (i->cell_index ()); - m_cells_to_write.insert (std::make_pair (i->cell_index (), filename_for_cell (i->cell_index (), layout))); - } write_instance (i->cell_inst (), layout, os); } diff --git a/src/plugins/streamers/magic/db_plugin/dbMAGWriter.h b/src/plugins/streamers/magic/db_plugin/dbMAGWriter.h index 672ca35fd..8727c3f89 100644 --- a/src/plugins/streamers/magic/db_plugin/dbMAGWriter.h +++ b/src/plugins/streamers/magic/db_plugin/dbMAGWriter.h @@ -90,20 +90,16 @@ private: tl::OutputStream *mp_stream; MAGWriterOptions m_options; tl::AbsoluteProgress m_progress; - std::set m_cells_written; - std::map m_cells_to_write; tl::URI m_base_uri; std::string m_ext; - std::map m_layer_names; size_t m_timestamp; std::map m_cell_id; double m_sf; std::string m_cellname; std::string filename_for_cell (db::cell_index_type ci, db::Layout &layout); - void write_cell (db::cell_index_type ci, db::Layout &layout, tl::OutputStream &os); - void do_write_cell (db::cell_index_type ci, db::Layout &layout, tl::OutputStream &os); - std::string layer_name (unsigned int li, const db::Layout &layout); + void write_cell (db::cell_index_type ci, const std::vector > &layers, db::Layout &layout, tl::OutputStream &os); + void do_write_cell (db::cell_index_type ci, const std::vector > &layers, db::Layout &layout, tl::OutputStream &os); void write_polygon (const db::Polygon &poly, const db::Layout &layout, tl::OutputStream &os); void write_label (const std::string &layer, const db::Text &text, const Layout &layout, tl::OutputStream &os); void write_instance (const db::CellInstArray &inst, const db::Layout &layout, tl::OutputStream &os); diff --git a/src/plugins/streamers/magic/db_plugin/gsiDeclDbMAG.cc b/src/plugins/streamers/magic/db_plugin/gsiDeclDbMAG.cc index 33bcbbf4c..67392fe05 100644 --- a/src/plugins/streamers/magic/db_plugin/gsiDeclDbMAG.cc +++ b/src/plugins/streamers/magic/db_plugin/gsiDeclDbMAG.cc @@ -246,6 +246,26 @@ static double get_mag_lambda_w (const db::SaveLayoutOptions *options) return options->get_options ().lambda; } +static void set_mag_write_timestamp (db::SaveLayoutOptions *options, bool f) +{ + options->get_options ().write_timestamp = f; +} + +static bool get_mag_write_timestamp (const db::SaveLayoutOptions *options) +{ + return options->get_options ().write_timestamp; +} + +static void set_mag_tech_w (db::SaveLayoutOptions *options, const std::string &t) +{ + options->get_options ().tech = t; +} + +static const std::string &get_mag_tech_w (const db::SaveLayoutOptions *options) +{ + return options->get_options ().tech; +} + // extend lay::SaveLayoutOptions with the MAG options static gsi::ClassExt mag_writer_options ( @@ -259,9 +279,31 @@ gsi::ClassExt mag_writer_options ( "\nThis property has been added in version 0.26.2.\n" ) + gsi::method_ext ("mag_lambda", &get_mag_lambda_w, - "@brief Get the lambda value\n" + "@brief Gets the lambda value\n" "See \\mag_lambda= method for a description of this attribute." "\nThis property has been added in version 0.26.2.\n" + ) + + gsi::method_ext ("write_timestamp=", &set_mag_write_timestamp, gsi::arg ("f"), + "@brief Specifies whether to write a timestamp\n" + "\n" + "If this attribute is set to false, the timestamp written is 0. This isn't correct in the strict sense but simplifies comparison of Magic files.\n" + "\nThis property has been added in version 0.26.2.\n" + ) + + gsi::method_ext ("write_timestamp", &get_mag_write_timestamp, + "@brief Gets a value indicating whether to write a timestamp\n" + "See \\write_timestamp= method for a description of this attribute.\n" + "\nThis property has been added in version 0.26.2.\n" + ) + + gsi::method_ext ("mag_tech=", &set_mag_tech_w, gsi::arg ("tech"), + "@brief Specifies the technology string used for writing\n" + "\n" + "If this string is empty, the writer will try to obtain the technology from the \"technology\" metadata attribute of the layout.\n" + "\nThis property has been added in version 0.26.2.\n" + ) + + gsi::method_ext ("mag_tech", &get_mag_tech_w, + "@brief Gets the technology string used for writing\n" + "See \\mag_tech= method for a description of this attribute." + "\nThis property has been added in version 0.26.2.\n" ), "" ); diff --git a/src/plugins/streamers/magic/lay_plugin/MAGWriterOptionPage.ui b/src/plugins/streamers/magic/lay_plugin/MAGWriterOptionPage.ui index 8f16a47f8..722a905b3 100644 --- a/src/plugins/streamers/magic/lay_plugin/MAGWriterOptionPage.ui +++ b/src/plugins/streamers/magic/lay_plugin/MAGWriterOptionPage.ui @@ -7,7 +7,7 @@ 0 0 619 - 209 + 250 @@ -35,9 +35,40 @@ Magic Writer Options + + + + + + + Zero timestamp + + + + + + + If checked, a zero timestamp is written (good for comparing files) + + + + + + + Leave this value empty to take the lambda value stored in the layout + + + + + + + Technology + + + @@ -52,13 +83,6 @@ - - - - Leave this value empty to take the lambda value stored in the layout - - - diff --git a/src/plugins/streamers/magic/lay_plugin/layMAGWriterPlugin.cc b/src/plugins/streamers/magic/lay_plugin/layMAGWriterPlugin.cc index d017cc186..f49c2fef2 100644 --- a/src/plugins/streamers/magic/lay_plugin/layMAGWriterPlugin.cc +++ b/src/plugins/streamers/magic/lay_plugin/layMAGWriterPlugin.cc @@ -60,6 +60,8 @@ MAGWriterOptionPage::setup (const db::FormatSpecificWriterOptions *o, const db:: } else { mp_ui->lambda_le->setText (tl::to_qstring (tl::to_string (options->lambda))); } + mp_ui->tech_le->setText (tl::to_qstring (options->tech)); + mp_ui->zero_ts_cbx->setChecked (! options->write_timestamp); } } @@ -73,6 +75,8 @@ MAGWriterOptionPage::commit (db::FormatSpecificWriterOptions *o, const db::Techn if (! l.isEmpty ()) { tl::from_string (tl::to_string (l), options->lambda); } + options->tech = tl::to_string (mp_ui->tech_le->text ().trimmed ()); + options->write_timestamp = ! mp_ui->zero_ts_cbx->isChecked (); } } diff --git a/src/plugins/streamers/magic/unit_tests/dbMAGReader.cc b/src/plugins/streamers/magic/unit_tests/dbMAGReader.cc index bd6a9042f..085040fbd 100644 --- a/src/plugins/streamers/magic/unit_tests/dbMAGReader.cc +++ b/src/plugins/streamers/magic/unit_tests/dbMAGReader.cc @@ -66,16 +66,12 @@ static void run_test (tl::TestBase *_this, const std::string &base, const char * reader.read (layout, options); } - // generate a "unique" name ... - unsigned int hash = 0; - for (const char *cp = file_au; *cp; ++cp) { - hash = (hash << 4) ^ (hash >> 4) ^ ((unsigned int) *cp); - } + std::string tc_name = layout.cell_name (*layout.begin_top_down ()); // normalize the layout by writing to GDS and reading from .. - std::string tmp_cif_file = _this->tmp_file (tl::sprintf ("tmp_%x.cif", hash)); - std::string tmp_mag_file = _this->tmp_file (tl::sprintf ("tmp_%x.mag", hash)); + std::string tmp_cif_file = _this->tmp_file (tl::sprintf ("%s.cif", tc_name)); + std::string tmp_mag_file = _this->tmp_file (tl::sprintf ("%s.mag", tc_name)); { tl::OutputStream stream (tmp_cif_file); @@ -142,6 +138,6 @@ static void run_test (tl::TestBase *_this, const std::string &base, const char * TEST(1) { - run_test (_this, tl::testsrc (), "mag_test.mag.gz", "mag_test_au.cif.gz"); + run_test (_this, tl::testsrc (), "MAG_TEST.mag.gz", "mag_test_au.cif.gz"); } diff --git a/src/tl/tl/tlTimer.h b/src/tl/tl/tlTimer.h index 4ac115abc..48302fa49 100644 --- a/src/tl/tl/tlTimer.h +++ b/src/tl/tl/tlTimer.h @@ -39,7 +39,7 @@ namespace tl * @brief clock_gettime is not implemented in Mac OS X 10.11 and lower * From: https://gist.githubusercontent.com/jbenet/1087739/raw/638b37f76cdd9dc46d617443cab27eac297e2ee3/current_utc_time.c */ -void current_utc_time (struct timespec *ts); +TL_PUBLIC void current_utc_time (struct timespec *ts); /** * @brief A basic timer class diff --git a/testdata/magic/mag_test.mag.gz b/testdata/magic/MAG_TEST.mag.gz similarity index 100% rename from testdata/magic/mag_test.mag.gz rename to testdata/magic/MAG_TEST.mag.gz diff --git a/testdata/magic/mag_test_au.cif.gz b/testdata/magic/mag_test_au.cif.gz index 4e145f7145d90215505c93f512ac3e7b96536b56..39342076a47fbc259891b1bbb10bc7e10d6eae2f 100644 GIT binary patch literal 443 zcmV;s0Yv^EiwFp7oZ(#n18revUvy=2bYEe0E@NqC0CiJsYr-%P{@!1413?EBa!Jz{ z`$>G6GKDeweQZoep;!<%@!zkxB=%}Ii|O;+J$Z7uq@&q-35T-U!{t<-&-)`tf!P>w zEHe-|K{XLEd|csq^M0+r&yRU9-vOFO++(s(7D7aCN`P+Du}f=~PFidvlC5W;GM3JlV`=6=dIxD@(~KoG zMBW;*oj$!4i(QciGlW-cN+_r##v-JtCL+QyLVLu#xYVcW^8rRx`BNUh;834nFc>@zn`5PhrsfcUdd~ lDCvqLwhxPAx+t#F4$%==#C@Wyo%#M2!7oE=(ul?c000J+(CYvI literal 443 zcmV;s0Yv^EiwFpkV&Gi>19WY0Ut?ooFgas2H7;XmW&m|l-)q7!5Pt7paRWhx3b~}| z5BsPSWj>6}_u*KTLbc$!iU0kYOJc9(-dcr0<#(7 zOlBZ(j%qGqc)!8Zc7LnCnrR*^UjfY{@*so7db3^T!4^(Mv#&4@o~IZN`ck zBJT}3?T>Fw@!90T0^tSQ5_VJ)V-eC+6A|GIVTX31M6kFCQ#|A$CDMOF)F2+0dLVV7 zp>*gf`>x&jW)Y0nMOD=yTE=%3Uu)MXM-;o