groups: move record name prepend into parser hooks
Also, accumulate config instead of replacing
This commit is contained in:
@ -26,6 +26,7 @@ typedef std::map<std::string, pvd::AnyScalar> options_t;
|
|||||||
typedef std::map<std::string, options_t> config_t;
|
typedef std::map<std::string, options_t> config_t;
|
||||||
|
|
||||||
struct context {
|
struct context {
|
||||||
|
const std::string chanprefix;
|
||||||
std::string msg;
|
std::string msg;
|
||||||
std::string group, field, key;
|
std::string group, field, key;
|
||||||
unsigned depth; // number of '{'s
|
unsigned depth; // number of '{'s
|
||||||
@ -34,9 +35,13 @@ struct context {
|
|||||||
// depth 2 - Group
|
// depth 2 - Group
|
||||||
// depth 3 - field
|
// 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()
|
void can_assign()
|
||||||
{
|
{
|
||||||
@ -69,7 +74,7 @@ struct context {
|
|||||||
fld.type = value.ref<std::string>();
|
fld.type = value.ref<std::string>();
|
||||||
|
|
||||||
} else if(key=="+channel") {
|
} else if(key=="+channel") {
|
||||||
fld.channel = value.ref<std::string>();
|
fld.channel = chanprefix + value.ref<std::string>();
|
||||||
|
|
||||||
} else if(key=="+id") {
|
} else if(key=="+id") {
|
||||||
fld.id = value.ref<std::string>();
|
fld.id = value.ref<std::string>();
|
||||||
@ -217,6 +222,7 @@ struct handler {
|
|||||||
}// namespace
|
}// namespace
|
||||||
|
|
||||||
void GroupConfig::parse(const char *txt,
|
void GroupConfig::parse(const char *txt,
|
||||||
|
const char *recname,
|
||||||
GroupConfig& result)
|
GroupConfig& result)
|
||||||
{
|
{
|
||||||
#ifndef EPICS_YAJL_VERSION
|
#ifndef EPICS_YAJL_VERSION
|
||||||
@ -228,7 +234,12 @@ void GroupConfig::parse(const char *txt,
|
|||||||
|
|
||||||
std::istringstream strm(txt);
|
std::istringstream strm(txt);
|
||||||
|
|
||||||
context ctxt;
|
std::string chanprefix;
|
||||||
|
if(recname) {
|
||||||
|
chanprefix = recname;
|
||||||
|
chanprefix += '.';
|
||||||
|
}
|
||||||
|
context ctxt(chanprefix, result);
|
||||||
|
|
||||||
#ifndef EPICS_YAJL_VERSION
|
#ifndef EPICS_YAJL_VERSION
|
||||||
handler handle(yajl_alloc(&conf_cbs, &conf, NULL, &ctxt));
|
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))
|
if(!pvd::yajl_parse_helper(strm, handle))
|
||||||
throw std::runtime_error(ctxt.msg);
|
throw std::runtime_error(ctxt.msg);
|
||||||
|
|
||||||
ctxt.conf.swap(result);
|
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,6 @@ struct PDBProcessor
|
|||||||
typedef std::map<std::string, GroupInfo> groups_t;
|
typedef std::map<std::string, GroupInfo> groups_t;
|
||||||
groups_t groups;
|
groups_t groups;
|
||||||
|
|
||||||
std::string recbase;
|
|
||||||
GroupInfo *curgroup;
|
GroupInfo *curgroup;
|
||||||
|
|
||||||
// validate trigger mappings and process into bit map form
|
// validate trigger mappings and process into bit map form
|
||||||
@ -196,13 +195,10 @@ struct PDBProcessor
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
GroupConfig conf;
|
GroupConfig conf;
|
||||||
GroupConfig::parse(json, conf);
|
GroupConfig::parse(json, rec.name(), conf);
|
||||||
if(!conf.warning.empty())
|
if(!conf.warning.empty())
|
||||||
fprintf(stderr, "%s: warning(s) from info(Q:group, ...\n%s", rec.name(), conf.warning.c_str());
|
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();
|
for(GroupConfig::groups_t::const_iterator git=conf.groups.begin(), gend=conf.groups.end();
|
||||||
git!=gend; ++git)
|
git!=gend; ++git)
|
||||||
{
|
{
|
||||||
@ -232,15 +228,15 @@ struct PDBProcessor
|
|||||||
|
|
||||||
GroupInfo::members_map_t::const_iterator oldgrp(curgroup->members_map.find(fldname));
|
GroupInfo::members_map_t::const_iterator oldgrp(curgroup->members_map.find(fldname));
|
||||||
if(oldgrp!=curgroup->members_map.end()) {
|
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(),
|
grpname.c_str(), fldname.c_str(),
|
||||||
recbase.c_str(), fld.channel.c_str());
|
fld.channel.c_str());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tr1::shared_ptr<PVIFBuilder> builder(PVIFBuilder::create(fld.type));
|
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().structID = fld.id;
|
||||||
curgroup->members.back().putorder = fld.putorder;
|
curgroup->members.back().putorder = fld.putorder;
|
||||||
curgroup->members_map[fldname] = (size_t)-1; // placeholder see below
|
curgroup->members_map[fldname] = (size_t)-1; // placeholder see below
|
||||||
|
@ -59,7 +59,7 @@ struct QSRV_API GroupConfig
|
|||||||
std::swap(warning, o.warning);
|
std::swap(warning, o.warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse(const char *txt,
|
static void parse(const char *txt, const char *recname,
|
||||||
GroupConfig& result);
|
GroupConfig& result);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@ void test_parse()
|
|||||||
" \"+atomic\":false,\n"
|
" \"+atomic\":false,\n"
|
||||||
" \"fld\":{\n"
|
" \"fld\":{\n"
|
||||||
" \"+type\": \"simple\","
|
" \"+type\": \"simple\","
|
||||||
|
" \"+channel\": \"VAL\","
|
||||||
" \"+putorder\": -4"
|
" \"+putorder\": -4"
|
||||||
" },\n"
|
" },\n"
|
||||||
" \"\":{\n"
|
" \"\":{\n"
|
||||||
@ -29,7 +30,7 @@ void test_parse()
|
|||||||
"}";
|
"}";
|
||||||
|
|
||||||
GroupConfig conf;
|
GroupConfig conf;
|
||||||
GroupConfig::parse(txt, conf);
|
GroupConfig::parse(txt, "rec", conf);
|
||||||
|
|
||||||
testOk(conf.warning.empty(), "Warnings: %s", conf.warning.c_str());
|
testOk(conf.warning.empty(), "Warnings: %s", conf.warning.c_str());
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ void test_parse()
|
|||||||
testOk1(conf.groups["grpa"].atomic_set);
|
testOk1(conf.groups["grpa"].atomic_set);
|
||||||
|
|
||||||
testEqual(conf.groups["grpa"].fields["fld"].type, "simple");
|
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["fld"].putorder, -4);
|
||||||
|
|
||||||
testEqual(conf.groups["grpa"].fields[""].type, "top");
|
testEqual(conf.groups["grpa"].fields[""].type, "top");
|
||||||
@ -49,15 +50,15 @@ void test_fail()
|
|||||||
|
|
||||||
{
|
{
|
||||||
GroupConfig conf;
|
GroupConfig conf;
|
||||||
testThrows(std::runtime_error, GroupConfig::parse("{", conf));
|
testThrows(std::runtime_error, GroupConfig::parse("{", "", conf));
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
GroupConfig 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;
|
GroupConfig conf;
|
||||||
testThrows(std::runtime_error, GroupConfig::parse("{\"G\":5}", conf));
|
testThrows(std::runtime_error, GroupConfig::parse("{\"G\":5}", "", conf));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user