Commit fecc762d by Maarten L. Hekkelman

- better link validation

- better output (quote reserved strings)
parent 1e406253
...@@ -82,16 +82,7 @@ inline bool isAnyPrint(int ch) ...@@ -82,16 +82,7 @@ inline bool isAnyPrint(int ch)
(ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kAnyPrintMask) != 0); (ch >= 0x20 and ch <= 0x7f and (kCharTraitsTable[ch - 0x20] & kAnyPrintMask) != 0);
} }
inline bool isUnquotedString(const char *s) bool isUnquotedString(const char *s);
{
bool result = isOrdinary(*s++);
while (result and *s != 0)
{
result = isNonBlank(*s);
++s;
}
return result;
}
// -------------------------------------------------------------------- // --------------------------------------------------------------------
......
...@@ -1900,11 +1900,16 @@ bool Category::hasParent(Row r, const Category &parentCat, const ValidateLink &l ...@@ -1900,11 +1900,16 @@ bool Category::hasParent(Row r, const Category &parentCat, const ValidateLink &l
if (mCatValidator->mMandatoryFields.count(name) and field.is_null()) if (mCatValidator->mMandatoryFields.count(name) and field.is_null())
cond = std::move(cond) and (Key(link.mParentKeys[ix]) == Empty()); cond = std::move(cond) and (Key(link.mParentKeys[ix]) == Empty());
} }
else else if (parentCat.mCatValidator->mMandatoryFields.count(link.mParentKeys[ix]))
{ {
const char *value = field.c_str(); const char *value = field.c_str();
cond = std::move(cond) and (Key(link.mParentKeys[ix]) == value); cond = std::move(cond) and (Key(link.mParentKeys[ix]) == value);
} }
else
{
const char *value = field.c_str();
cond = std::move(cond) and (Key(link.mParentKeys[ix]) == value or Key(link.mParentKeys[ix]) == Empty());
}
} }
if (result and not cond.empty()) if (result and not cond.empty())
...@@ -2201,9 +2206,27 @@ void Category::validateLinks() const ...@@ -2201,9 +2206,27 @@ void Category::validateLinks() const
size_t missing = 0; size_t missing = 0;
for (auto r : *this) for (auto r : *this)
if (not hasParent(r, *parentCat, *link)) if (not hasParent(r, *parentCat, *link))
{
if (cif::VERBOSE > 1)
{
if (missing == 0)
{
std::cerr << "Links for " << link->mLinkGroupLabel << " are incomplete" << std::endl
<< " These are the items in " << mName << " that don't have matching parent items in " << parentCat->mName << std::endl
<< std::endl;
}
for (auto k : link->mChildKeys)
std::cerr << k << ": " << r[k].as<std::string>() << std::endl;
std::cerr << std::endl;
}
++missing; ++missing;
if (missing and VERBOSE >= 0) }
if (missing and VERBOSE == 1)
{ {
std::cerr << "Links for " << link->mLinkGroupLabel << " are incomplete" << std::endl std::cerr << "Links for " << link->mLinkGroupLabel << " are incomplete" << std::endl
<< " There are " << missing << " items in " << mName << " that don't have matching parent items in " << parentCat->mName << std::endl; << " There are " << missing << " items in " << mName << " that don't have matching parent items in " << parentCat->mName << std::endl;
......
...@@ -82,6 +82,29 @@ const char *SacParser::kValueName[] = { ...@@ -82,6 +82,29 @@ const char *SacParser::kValueName[] = {
// -------------------------------------------------------------------- // --------------------------------------------------------------------
bool isUnquotedString(const char *s)
{
auto ss = s;
bool result = isOrdinary(*s++);
while (result and *s != 0)
{
result = isNonBlank(*s);
++s;
}
// but be careful it does not contain e.g. stop_
if (result)
{
const std::regex reservedRx(R"(^(?:data|save|loop|stop|global)_.+)", std::regex_constants::icase);
result = not std::regex_match(ss, reservedRx);
}
return result;
}
// --------------------------------------------------------------------
SacParser::SacParser(std::istream &is, bool init) SacParser::SacParser(std::istream &is, bool init)
: mData(is) : mData(is)
{ {
......
...@@ -1819,4 +1819,39 @@ _test.text ?? ...@@ -1819,4 +1819,39 @@ _test.text ??
const auto &[text] = r.get<std::string>({"text"}); const auto &[text] = r.get<std::string>({"text"});
BOOST_CHECK_EQUAL(text, "??"); BOOST_CHECK_EQUAL(text, "??");
} }
}
BOOST_AUTO_TEST_CASE(output_test_1)
{
auto data1 = R"(
data_Q
_test.text "stop_the_crap"
)"_cf;
auto &db1 = data1.firstDatablock();
auto &test1 = db1["test"];
BOOST_CHECK_EQUAL(test1.size(), 1);
for (auto r : test1)
{
const auto &[text] = r.get<std::string>({"text"});
BOOST_CHECK_EQUAL(text, "stop_the_crap");
}
std::stringstream ss;
data1.save(ss);
auto data2 = cif::File(ss);
auto &db2 = data2.firstDatablock();
auto &test2 = db2["test"];
BOOST_CHECK_EQUAL(test2.size(), 1);
for (auto r : test2)
{
const auto &[text] = r.get<std::string>({"text"});
BOOST_CHECK_EQUAL(text, "stop_the_crap");
}
} }
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment