This commit is contained in:
Matthias Koefferlein 2025-04-27 20:55:11 +02:00
parent f1b35d0826
commit e76be5b071
7 changed files with 176 additions and 29 deletions

View File

@ -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<db::MALYReaderOptions> ("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<std::vector<std::string>, db::MALYReaderOptions> (&db::MALYReaderOptions::lib_paths, "lib-paths",
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, "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<db::MALYWriterOptions> ("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

View File

@ -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
*/

View File

@ -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<db::MALYReaderOptions> ();
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)
{

View File

@ -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 ();
};
}

View File

@ -28,7 +28,7 @@
#include <stdlib.h>
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<std::string> *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);

View File

@ -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

15
testdata/maly/MALY_TEST.maly vendored Normal file
View File

@ -0,0 +1,15 @@
// a comment
BEGIN /* a multiline comment
*/ MALY
// a comment
SREF " \"// /*hello*/ " SIZE
+ 10,10