diff --git a/src/db/db/dbCIF.cc b/src/db/db/dbCIF.cc index 6935724c4..9026f6992 100644 --- a/src/db/db/dbCIF.cc +++ b/src/db/db/dbCIF.cc @@ -56,6 +56,14 @@ public: virtual std::string format_title () const { return "CIF (Caltech interchange format)"; } virtual std::string file_format () const { return "CIF files (*.CIF *.cif *.cif.gz *.CIF.gz)"; } + static tl::Extractor &skip_blanks (tl::Extractor &ex) + { + while (! ex.at_end () && *ex != ';' && *ex != '-' && *ex != '(' && *ex != ')' && !isalnum(*ex)) { + ++ex; + } + return ex; + } + virtual bool detect (tl::InputStream &s) const { try { @@ -67,11 +75,12 @@ public: int n = 0; tl::Extractor ex (head.c_str ()); - while (! ex.at_end ()) { + while (! skip_blanks (ex).at_end ()) { - if (ex.test ("(")) { + if (*ex == '(') { // read over comments + ++ex; int bl = 0; while (! ex.at_end () && (*ex != ')' || bl > 0)) { // check for nested comments (bl is the nesting level) @@ -86,18 +95,36 @@ public: ++ex; } - } else if (ex.test (";")) { + } else if (*ex == ';') { // ignore ; + ++ex; - } else if ((ex.test ("DS ") && ex.try_read (n)) || ex.test ("L ")) { + } else if (*ex == 'L') { - // first command must be "DS num", "L" - return true; + // first command must be "DS num", or "L shortname" + ++ex; + skip_blanks (ex); + return ! ex.at_end () && isalnum (*ex); - } else if (ex.test ("9")) { + } else if (*ex == 'D') { + + // first command must be "DS num", or "L" + ++ex; + skip_blanks (ex); + if (ex.at_end () || *ex != 'S') { + break; // not "DS" + } + ++ex; + skip_blanks (ex); + if (ex.try_read (n)) { + return true; + } + + } else if (*ex == '9') { // read over 9...; commands + ++ex; while (! ex.at_end () && *ex != ';') { ++ex; } diff --git a/src/db/unit_tests/dbCIFReader.cc b/src/db/unit_tests/dbCIFReader.cc index 65b7de45e..9586a817a 100644 --- a/src/db/unit_tests/dbCIFReader.cc +++ b/src/db/unit_tests/dbCIFReader.cc @@ -31,7 +31,7 @@ #include #include -static void run_test (tl::TestBase *_this, const char *file, const char *file_au, const char *map = 0, double dbu = 0.001, bool dummy_calls = false, bool blank_sep = false) +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, bool dummy_calls = false, bool blank_sep = false) { db::CIFReaderOptions *opt = new db::CIFReaderOptions(); opt->dbu = dbu; @@ -60,7 +60,7 @@ static void run_test (tl::TestBase *_this, const char *file, const char *file_au db::Layout layout (&m), layout2 (&m), layout2_cif (&m), layout_au (&m); { - std::string fn (tl::testsrc_private ()); + std::string fn (base); fn += "/testdata/cif/"; fn += file; tl::InputStream stream (fn); @@ -120,7 +120,7 @@ static void run_test (tl::TestBase *_this, const char *file, const char *file_au } { - std::string fn (tl::testsrc_private ()); + std::string fn (base); fn += "/testdata/cif/"; fn += file_au; tl::InputStream stream (fn); @@ -141,46 +141,52 @@ static void run_test (tl::TestBase *_this, const char *file, const char *file_au TEST(1a) { - run_test (_this, "t1.cif.gz", "t1a_au.gds.gz"); + run_test (_this, tl::testsrc_private (), "t1.cif.gz", "t1a_au.gds.gz"); } TEST(1b) { - run_test (_this, "t1.cif.gz", "t1b_au.gds.gz", 0, 0.01); + run_test (_this, tl::testsrc_private (), "t1.cif.gz", "t1b_au.gds.gz", 0, 0.01); } TEST(1c) { - run_test (_this, "t1.cif.gz", "t1b_au.gds.gz", 0, 0.01, true); + run_test (_this, tl::testsrc_private (), "t1.cif.gz", "t1b_au.gds.gz", 0, 0.01, true); } TEST(1d) { - run_test (_this, "t1.cif.gz", "t1b_au.gds.gz", 0, 0.01, false, true); + run_test (_this, tl::testsrc_private (), "t1.cif.gz", "t1b_au.gds.gz", 0, 0.01, false, true); } TEST(2) { - run_test (_this, "t2.cif.gz", "t2_au.gds.gz"); + run_test (_this, tl::testsrc_private (), "t2.cif.gz", "t2_au.gds.gz"); } TEST(3a) { - run_test (_this, "t3.cif.gz", "t3a_au.gds.gz", "CAA:43,CCA:48,CCP:47,CMF:49,CMS:51,CPG:46,CSN:45,CSP:44,CVA:50,CWN:42,XP:26"); + run_test (_this, tl::testsrc_private (), "t3.cif.gz", "t3a_au.gds.gz", "CAA:43,CCA:48,CCP:47,CMF:49,CMS:51,CPG:46,CSN:45,CSP:44,CVA:50,CWN:42,XP:26"); } TEST(3b) { - run_test (_this, "t3.cif.gz", "t3b_au.gds.gz", "CAA:43,CCA:48,CCP:47,CMF:49,CMS:51,CPG:46,CSN:45,CSP:44,CVA:50,CWN:42,XP:26", 0.00012); + run_test (_this, tl::testsrc_private (), "t3.cif.gz", "t3b_au.gds.gz", "CAA:43,CCA:48,CCP:47,CMF:49,CMS:51,CPG:46,CSN:45,CSP:44,CVA:50,CWN:42,XP:26", 0.00012); } TEST(4) { - run_test (_this, "t4.cif.gz", "t4_au.gds.gz"); + run_test (_this, tl::testsrc_private (), "t4.cif.gz", "t4_au.gds.gz"); } TEST(5) { - run_test (_this, "t5.cif.gz", "t5_au.gds.gz"); + run_test (_this, tl::testsrc_private (), "t5.cif.gz", "t5_au.gds.gz"); +} + +// Issue #28 +TEST(lasi) +{ + run_test (_this, tl::testsrc (), "lasi.cif.gz", "lasi_au.gds.gz"); } diff --git a/testdata/cif/lasi.cif.gz b/testdata/cif/lasi.cif.gz new file mode 100644 index 000000000..a9a4ffb74 Binary files /dev/null and b/testdata/cif/lasi.cif.gz differ diff --git a/testdata/cif/lasi.gds.gz b/testdata/cif/lasi.gds.gz new file mode 100644 index 000000000..d59f20c40 Binary files /dev/null and b/testdata/cif/lasi.gds.gz differ