mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
f1b35d0826
commit
e76be5b071
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
// a comment
|
||||
|
||||
BEGIN /* a multiline comment
|
||||
|
||||
|
||||
*/ MALY
|
||||
|
||||
// a comment
|
||||
|
||||
SREF " \"// /*hello*/ " SIZE
|
||||
+ 10,10
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in New Issue