diff --git a/src/plugins/streamers/maly/db_plugin/dbMALY.cc b/src/plugins/streamers/maly/db_plugin/dbMALY.cc index 57d67e416..b53b4b449 100644 --- a/src/plugins/streamers/maly/db_plugin/dbMALY.cc +++ b/src/plugins/streamers/maly/db_plugin/dbMALY.cc @@ -57,7 +57,8 @@ public: virtual bool detect (tl::InputStream &s) const { - return false; // @@@ + db::MALYReader reader (s); + return reader.test (); } virtual ReaderBase *create_reader (tl::InputStream &s) const @@ -68,7 +69,6 @@ public: virtual WriterBase *create_writer () const { return 0; - // @@@ return new db::MALYWriter (); } virtual bool can_read () const @@ -79,36 +79,16 @@ public: virtual bool can_write () const { return false; - // @@@ return true; } virtual tl::XMLElementBase *xml_reader_options_element () const { return new db::ReaderOptionsXMLElement ("mag", - tl::make_member (&db::MALYReaderOptions::dbu, "dbu") - /* @@@ - tl::make_member (&db::MALYReaderOptions::lambda, "lambda") + + tl::make_member (&db::MALYReaderOptions::dbu, "dbu") + tl::make_member (&db::MALYReaderOptions::layer_map, "layer-map") + - tl::make_member (&db::MALYReaderOptions::create_other_layers, "create-other-layers") + - tl::make_member (&db::MALYReaderOptions::keep_layer_names, "keep-layer-names") + - tl::make_member (&db::MALYReaderOptions::merge, "merge") + - tl::make_element, db::MALYReaderOptions> (&db::MALYReaderOptions::lib_paths, "lib-paths", - tl::make_member::const_iterator, std::vector > (&std::vector::begin, &std::vector::end, &std::vector::push_back, "lib-path") - ) - */ + tl::make_member (&db::MALYReaderOptions::create_other_layers, "create-other-layers") ); } - - /* @@@ - virtual tl::XMLElementBase *xml_writer_options_element () const - { - return new db::WriterOptionsXMLElement ("mag", - tl::make_member (&db::MALYWriterOptions::lambda, "lambda") + - tl::make_member (&db::MALYWriterOptions::tech, "tech") + - tl::make_member (&db::MALYWriterOptions::write_timestamp, "write-timestamp") - ); - } - @@@ */ }; // NOTE: Because MALY has such a high degree of syntactic freedom, the detection is somewhat diff --git a/src/plugins/streamers/maly/db_plugin/dbMALY.h b/src/plugins/streamers/maly/db_plugin/dbMALY.h index c4f81e8f4..ec904e969 100644 --- a/src/plugins/streamers/maly/db_plugin/dbMALY.h +++ b/src/plugins/streamers/maly/db_plugin/dbMALY.h @@ -134,6 +134,7 @@ public: */ class MALYStructure { +public: /** * @brief Default constructor */ @@ -210,6 +211,7 @@ class MALYStructure */ class MALYMask { +public: /** * @brief Default constructor */ @@ -245,6 +247,7 @@ class MALYMask */ class MALYData { +public: /** * @brief Default constructor */ diff --git a/src/plugins/streamers/maly/db_plugin/dbMALYReader.cc b/src/plugins/streamers/maly/db_plugin/dbMALYReader.cc index 1d550ca9e..2352fe8ed 100644 --- a/src/plugins/streamers/maly/db_plugin/dbMALYReader.cc +++ b/src/plugins/streamers/maly/db_plugin/dbMALYReader.cc @@ -61,6 +61,22 @@ MALYReader::~MALYReader () // .. nothing yet .. } +bool +MALYReader::test () +{ + return true; // @@@ + try { + + std::string rec = read_record (); + + tl::Extractor ex (rec.c_str ()); + return ex.test ("BEGIN") && ex.test ("MALY"); + + } catch (...) { + return false; + } +} + const LayerMap & MALYReader::read (db::Layout &layout) { @@ -74,12 +90,135 @@ MALYReader::read (db::Layout &layout, const db::LoadLayoutOptions &options) prepare_layers (layout); + const db::MALYReaderOptions &specific_options = options.get_options (); + m_dbu = specific_options.dbu; + + set_layer_map (specific_options.layer_map); + set_create_layers (specific_options.create_other_layers); + // @@@ set_keep_layer_names (specific_options.keep_layer_names); + set_keep_layer_names (true); + + MALYData data = read_maly_file (); + // @@@ finish_layers (layout); return layer_map_out (); } +std::string +MALYReader::read_record () +{ + while (! m_stream.at_end ()) { + std::string r = read_record_internal (); + tl::Extractor ex (r.c_str ()); + if (ex.test ("+")) { + error (tl::to_string (tr ("'+' character past first column - did you mean to continue a line?"))); + } else if (! ex.at_end ()) { + return r; + } + } + + return std::string (); +} + +std::string +MALYReader::read_record_internal () +{ + std::string rec; + + while (! m_stream.at_end ()) { + + char c = m_stream.get_char (); + + // skip comments + if (c == '/') { + char cc = m_stream.peek_char (); + if (cc == '/') { + while (! m_stream.at_end () && (c = m_stream.get_char ()) != '\n') + ; + if (m_stream.at_end ()) { + break; + } + } else if (cc == '*') { + m_stream.get_char (); // eat leading "*" + while (! m_stream.at_end () && (m_stream.get_char () != '*' || m_stream.peek_char () != '/')) + ; + if (m_stream.at_end ()) { + error (tl::to_string (tr ("/*...*/ comment not closed"))); + } + m_stream.get_char (); // eat trailing "/" + if (m_stream.at_end ()) { + break; + } + c = m_stream.get_char (); + } + } + + if (c == '\n') { + if (m_stream.peek_char () == '+') { + // continuation line + m_stream.get_char (); // eat "+" + if (m_stream.at_end ()) { + break; + } + c = m_stream.get_char (); + } else { + break; + } + } + + if (c == '"' || c == '\'') { + + rec += c; + + // skip quoted string + char quote = c; + while (! m_stream.at_end ()) { + c = m_stream.get_char (); + rec += c; + if (c == quote) { + quote = 0; + break; + } else if (c == '\\') { + if (m_stream.at_end ()) { + error (tl::to_string (tr ("Unexpected end of file inside quotee string"))); + } + c = m_stream.get_char (); + rec += c; + } else if (c == '\n') { + error (tl::to_string (tr ("Line break inside quoted string"))); + } + } + + if (quote) { + error (tl::to_string (tr ("Unexpected end of file inside quotee string"))); + } + + } else { + rec += c; + } + + } + + return rec; +} + +MALYData +MALYReader::read_maly_file () +{ + // @@@ + std::cout << "@@@ BEGIN_MALY" << std::endl; + std::string rec; + while (! (rec = read_record ()).empty ()) { + std::cout << rec << std::endl; + } + std::cout << "@@@ END_MALY" << std::endl; + // @@@ + + return MALYData (); // @@@ +} + void MALYReader::error (const std::string &msg) { diff --git a/src/plugins/streamers/maly/db_plugin/dbMALYReader.h b/src/plugins/streamers/maly/db_plugin/dbMALYReader.h index f60f7ebb8..981d3419a 100644 --- a/src/plugins/streamers/maly/db_plugin/dbMALYReader.h +++ b/src/plugins/streamers/maly/db_plugin/dbMALYReader.h @@ -76,11 +76,18 @@ public: */ MALYReader (tl::InputStream &s); - /** + /** * @brief Destructor */ ~MALYReader (); + /** + * @brief Tests, if the stream is a valid MALY file + * + * This method can be used for the format detection + */ + bool test (); + /** * @brief The basic read method * @@ -140,6 +147,9 @@ private: void do_read (db::Layout &layout, db::cell_index_type to_cell, tl::TextInputStream &stream); std::string resolve_path(const std::string &path); + MALYData read_maly_file (); + std::string read_record (); + std::string read_record_internal (); }; } diff --git a/src/plugins/streamers/maly/unit_tests/dbMALYReader.cc b/src/plugins/streamers/maly/unit_tests/dbMALYReaderTests.cc similarity index 92% rename from src/plugins/streamers/maly/unit_tests/dbMALYReader.cc rename to src/plugins/streamers/maly/unit_tests/dbMALYReaderTests.cc index d43dbe0cc..cb3f749c3 100644 --- a/src/plugins/streamers/maly/unit_tests/dbMALYReader.cc +++ b/src/plugins/streamers/maly/unit_tests/dbMALYReaderTests.cc @@ -28,7 +28,7 @@ #include -static void run_test (tl::TestBase *_this, const std::string &base, const char *file, const char *file_au, const char *map = 0, double lambda = 0.1, double dbu = 0.001, const std::vector *lib_paths = 0) +static void run_test (tl::TestBase *_this, const std::string &base, const char *file, const char *file_au, const char *map = 0, double dbu = 0.001) { db::MALYReaderOptions *opt = new db::MALYReaderOptions(); opt->dbu = dbu; @@ -54,7 +54,7 @@ static void run_test (tl::TestBase *_this, const std::string &base, const char * options.set_options (opt); db::Manager m (false); - db::Layout layout (&m), layout2 (&m), layout2_mag (&m), layout_au (&m); + db::Layout layout (&m), layout2 (&m), layout_au (&m); { std::string fn (base); @@ -65,12 +65,12 @@ static void run_test (tl::TestBase *_this, const std::string &base, const char * reader.read (layout, options); } + tl_assert (layout.begin_top_down () != layout.end_top_down ()); std::string tc_name = layout.cell_name (*layout.begin_top_down ()); // normalize the layout by writing to OASIS and reading from .. std::string tmp_oas_file = _this->tmp_file (tl::sprintf ("%s.oas", tc_name)); - std::string tmp_maly_file = _this->tmp_file (tl::sprintf ("%s.mag", tc_name)); { tl::OutputStream stream (tmp_oas_file); diff --git a/src/plugins/streamers/maly/unit_tests/unit_tests.pro b/src/plugins/streamers/maly/unit_tests/unit_tests.pro index 7a6319ee6..a9d89c591 100644 --- a/src/plugins/streamers/maly/unit_tests/unit_tests.pro +++ b/src/plugins/streamers/maly/unit_tests/unit_tests.pro @@ -6,7 +6,7 @@ TARGET = maly_tests include($$PWD/../../../../lib_ut.pri) SOURCES = \ - dbMALYReader.cc \ + dbMALYReaderTests.cc INCLUDEPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common DEPENDPATH += $$LAY_INC $$TL_INC $$DB_INC $$GSI_INC $$PWD/../db_plugin $$PWD/../../../common diff --git a/testdata/maly/MALY_TEST.maly b/testdata/maly/MALY_TEST.maly new file mode 100644 index 000000000..0fd08fc48 --- /dev/null +++ b/testdata/maly/MALY_TEST.maly @@ -0,0 +1,15 @@ + +// a comment + +BEGIN /* a multiline comment + + +*/ MALY + +// a comment + +SREF " \"// /*hello*/ " SIZE ++ 10,10 + + +