groups: move record name prepend into parser hooks

Also, accumulate config instead of replacing
This commit is contained in:
Michael Davidsaver
2020-05-31 09:51:22 -07:00
parent b9d3ad8f90
commit f5278ef4ac
4 changed files with 26 additions and 20 deletions

View File

@ -26,6 +26,7 @@ typedef std::map<std::string, pvd::AnyScalar> options_t;
typedef std::map<std::string, options_t> config_t;
struct context {
const std::string chanprefix;
std::string msg;
std::string group, field, key;
unsigned depth; // number of '{'s
@ -34,9 +35,13 @@ struct context {
// depth 2 - Group
// depth 3 - field
context() :depth(0u) {}
context(const std::string& chanprefix, GroupConfig& conf)
:chanprefix(chanprefix)
,depth(0u)
,conf(conf)
{}
GroupConfig conf;
GroupConfig& conf;
void can_assign()
{
@ -69,7 +74,7 @@ struct context {
fld.type = value.ref<std::string>();
} else if(key=="+channel") {
fld.channel = value.ref<std::string>();
fld.channel = chanprefix + value.ref<std::string>();
} else if(key=="+id") {
fld.id = value.ref<std::string>();
@ -217,6 +222,7 @@ struct handler {
}// namespace
void GroupConfig::parse(const char *txt,
const char *recname,
GroupConfig& result)
{
#ifndef EPICS_YAJL_VERSION
@ -228,7 +234,12 @@ void GroupConfig::parse(const char *txt,
std::istringstream strm(txt);
context ctxt;
std::string chanprefix;
if(recname) {
chanprefix = recname;
chanprefix += '.';
}
context ctxt(chanprefix, result);
#ifndef EPICS_YAJL_VERSION
handler handle(yajl_alloc(&conf_cbs, &conf, NULL, &ctxt));
@ -240,6 +251,4 @@ void GroupConfig::parse(const char *txt,
if(!pvd::yajl_parse_helper(strm, handle))
throw std::runtime_error(ctxt.msg);
ctxt.conf.swap(result);
}

View File

@ -100,7 +100,6 @@ struct PDBProcessor
typedef std::map<std::string, GroupInfo> groups_t;
groups_t groups;
std::string recbase;
GroupInfo *curgroup;
// validate trigger mappings and process into bit map form
@ -196,13 +195,10 @@ struct PDBProcessor
try {
GroupConfig conf;
GroupConfig::parse(json, conf);
GroupConfig::parse(json, rec.name(), conf);
if(!conf.warning.empty())
fprintf(stderr, "%s: warning(s) from info(Q:group, ...\n%s", rec.name(), conf.warning.c_str());
recbase = rec.name();
recbase += ".";
for(GroupConfig::groups_t::const_iterator git=conf.groups.begin(), gend=conf.groups.end();
git!=gend; ++git)
{
@ -232,15 +228,15 @@ struct PDBProcessor
GroupInfo::members_map_t::const_iterator oldgrp(curgroup->members_map.find(fldname));
if(oldgrp!=curgroup->members_map.end()) {
fprintf(stderr, "%s.%s Warning: ignoring duplicate mapping %s%s\n",
fprintf(stderr, "%s.%s Warning: ignoring duplicate mapping %s\n",
grpname.c_str(), fldname.c_str(),
recbase.c_str(), fld.channel.c_str());
fld.channel.c_str());
continue;
}
std::tr1::shared_ptr<PVIFBuilder> builder(PVIFBuilder::create(fld.type));
curgroup->members.push_back(GroupMemberInfo(fld.channel.empty() ? fld.channel : recbase + fld.channel, fldname, builder));
curgroup->members.push_back(GroupMemberInfo(fld.channel, fldname, builder));
curgroup->members.back().structID = fld.id;
curgroup->members.back().putorder = fld.putorder;
curgroup->members_map[fldname] = (size_t)-1; // placeholder see below

View File

@ -59,7 +59,7 @@ struct QSRV_API GroupConfig
std::swap(warning, o.warning);
}
static void parse(const char *txt,
static void parse(const char *txt, const char *recname,
GroupConfig& result);
};

View File

@ -18,6 +18,7 @@ void test_parse()
" \"+atomic\":false,\n"
" \"fld\":{\n"
" \"+type\": \"simple\","
" \"+channel\": \"VAL\","
" \"+putorder\": -4"
" },\n"
" \"\":{\n"
@ -29,7 +30,7 @@ void test_parse()
"}";
GroupConfig conf;
GroupConfig::parse(txt, conf);
GroupConfig::parse(txt, "rec", conf);
testOk(conf.warning.empty(), "Warnings: %s", conf.warning.c_str());
@ -37,7 +38,7 @@ void test_parse()
testOk1(conf.groups["grpa"].atomic_set);
testEqual(conf.groups["grpa"].fields["fld"].type, "simple");
testEqual(conf.groups["grpa"].fields["fld"].channel, "");
testEqual(conf.groups["grpa"].fields["fld"].channel, "rec.VAL");
testEqual(conf.groups["grpa"].fields["fld"].putorder, -4);
testEqual(conf.groups["grpa"].fields[""].type, "top");
@ -49,15 +50,15 @@ void test_fail()
{
GroupConfig conf;
testThrows(std::runtime_error, GroupConfig::parse("{", conf));
testThrows(std::runtime_error, GroupConfig::parse("{", "", conf));
}
{
GroupConfig conf;
testThrows(std::runtime_error, GroupConfig::parse("{\"G\":{\"F\":{\"K\":{}}}}", conf));
testThrows(std::runtime_error, GroupConfig::parse("{\"G\":{\"F\":{\"K\":{}}}}", "", conf));
}
{
GroupConfig conf;
testThrows(std::runtime_error, GroupConfig::parse("{\"G\":5}", conf));
testThrows(std::runtime_error, GroupConfig::parse("{\"G\":5}", "", conf));
}
}