Split dbJLinkInit, JLinks are now parsed at load-time
This commit is contained in:
+33
-17
@@ -37,7 +37,6 @@
|
||||
typedef struct parseContext {
|
||||
jlink *pjlink;
|
||||
jlink *product;
|
||||
struct link *plink;
|
||||
short dbfType;
|
||||
short jsonDepth;
|
||||
short linkDepth;
|
||||
@@ -56,12 +55,23 @@ static int dbjl_value(parseContext *parser, jlif_result result) {
|
||||
parser->jsonDepth, parser->linkDepth, parser->key_is_link);
|
||||
}
|
||||
|
||||
if (result == jlif_stop && pjlink) {
|
||||
jlink *parent;
|
||||
|
||||
while ((parent = pjlink->parent)) {
|
||||
pjlink->pif->free_jlink(pjlink);
|
||||
pjlink = parent;
|
||||
}
|
||||
pjlink->pif->free_jlink(pjlink);
|
||||
}
|
||||
|
||||
if (result == jlif_stop || parser->linkDepth > 0)
|
||||
return result;
|
||||
|
||||
parser->product = pjlink;
|
||||
parser->key_is_link = 0;
|
||||
parser->pjlink = pjlink->parent;
|
||||
if (pjlink)
|
||||
parser->pjlink = pjlink->parent;
|
||||
|
||||
IFDEBUG(8)
|
||||
printf("dbjl_value: product = %p\n", pjlink);
|
||||
@@ -172,8 +182,8 @@ static int dbjl_map_key(void *ctx, const unsigned char *key, unsigned len) {
|
||||
|
||||
if (!parser->key_is_link) {
|
||||
if (!pjlink) {
|
||||
errlogPrintf("dbJLinkInit: Illegal second link key '%.*s' seen for %s\n",
|
||||
len, key, parser->plink->precord->name);
|
||||
errlogPrintf("dbJLinkInit: Illegal second link key '%.*s'\n",
|
||||
len, key);
|
||||
return jlif_stop;
|
||||
}
|
||||
|
||||
@@ -201,8 +211,8 @@ static int dbjl_map_key(void *ctx, const unsigned char *key, unsigned len) {
|
||||
|
||||
linkSup = dbFindLinkSup(pdbbase, link_name);
|
||||
if (!linkSup) {
|
||||
errlogPrintf("dbJLinkInit: Link type '%s' not found for %s\n",
|
||||
link_name, parser->plink->precord->name);
|
||||
errlogPrintf("dbJLinkInit: Link type '%s' not found\n",
|
||||
link_name);
|
||||
return jlif_stop;
|
||||
}
|
||||
|
||||
@@ -213,7 +223,7 @@ static int dbjl_map_key(void *ctx, const unsigned char *key, unsigned len) {
|
||||
return jlif_stop;
|
||||
}
|
||||
|
||||
pjlink = pjlif->alloc_jlink(parser->plink, parser->dbfType);
|
||||
pjlink = pjlif->alloc_jlink(parser->dbfType);
|
||||
if (!pjlink) {
|
||||
errlogPrintf("dbJLinkInit: Out of memory\n");
|
||||
return jlif_stop;
|
||||
@@ -307,22 +317,21 @@ static yajl_callbacks dbjl_callbacks = {
|
||||
static const yajl_parser_config dbjl_config =
|
||||
{ 0, 0 }; /* allowComments = NO, checkUTF8 = NO */
|
||||
|
||||
long dbJLinkInit(struct link *plink, short dbfType)
|
||||
long dbJLinkParse(const char *json, size_t jlen, short dbfType,
|
||||
jlink **ppjlink)
|
||||
{
|
||||
parseContext context, *parser = &context;
|
||||
yajl_alloc_funcs dbjl_allocs;
|
||||
yajl_handle yh;
|
||||
yajl_status ys;
|
||||
const char *json = plink->value.json.string;
|
||||
size_t jlen = strlen(json);
|
||||
long status;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("dbJLinkInit(\"%s.????\", %d)\n", plink->precord->name, dbfType);
|
||||
printf("dbJLinkInit(\"%.*s\", %d, %p)\n",
|
||||
(int) jlen, json, dbfType, ppjlink);
|
||||
|
||||
parser->pjlink = NULL;
|
||||
parser->product = NULL;
|
||||
parser->plink = plink;
|
||||
parser->dbfType = dbfType;
|
||||
parser->jsonDepth = 0;
|
||||
parser->linkDepth = 0;
|
||||
@@ -343,14 +352,10 @@ long dbJLinkInit(struct link *plink, short dbfType)
|
||||
|
||||
switch (ys) {
|
||||
unsigned char *err;
|
||||
jlink *pjlink;
|
||||
|
||||
case yajl_status_ok:
|
||||
assert(parser->jsonDepth == 0);
|
||||
pjlink = parser->product;
|
||||
assert(pjlink);
|
||||
plink->value.json.jlink = pjlink;
|
||||
plink->lset = pjlink->pif->get_lset(pjlink);
|
||||
*ppjlink = parser->product;
|
||||
status = 0;
|
||||
break;
|
||||
|
||||
@@ -367,4 +372,15 @@ long dbJLinkInit(struct link *plink, short dbfType)
|
||||
return status;
|
||||
}
|
||||
|
||||
long dbJLinkInit(struct link *plink)
|
||||
{
|
||||
jlink *pjlink;
|
||||
|
||||
assert(plink);
|
||||
pjlink = plink->value.json.jlink;
|
||||
|
||||
if (pjlink)
|
||||
plink->lset = pjlink->pif->get_lset(pjlink, plink);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ typedef struct jlink {
|
||||
|
||||
typedef struct jlif {
|
||||
const char *name;
|
||||
jlink* (*alloc_jlink)(struct link *, short dbfType);
|
||||
jlink* (*alloc_jlink)(short dbfType);
|
||||
void (*free_jlink)(jlink *);
|
||||
jlif_result (*start_parse)(jlink *);
|
||||
jlif_result (*parse_null)(jlink *);
|
||||
@@ -56,11 +56,13 @@ typedef struct jlif {
|
||||
jlif_result (*parse_start_array)(jlink *);
|
||||
jlif_result (*parse_end_array)(jlink *);
|
||||
jlif_result (*end_parse)(jlink *);
|
||||
struct lset* (*get_lset)(const jlink *);
|
||||
struct lset* (*get_lset)(const jlink *, struct link *);
|
||||
void (*report)(const jlink *);
|
||||
} jlif;
|
||||
|
||||
epicsShareFunc long dbJLinkInit(struct link *plink, short dbfType);
|
||||
epicsShareFunc long dbJLinkParse(const char *json, size_t len, short dbfType,
|
||||
jlink **ppjlink);
|
||||
epicsShareFunc long dbJLinkInit(struct link *plink);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+2
-2
@@ -79,7 +79,7 @@ void dbInitLink(struct link *plink, short dbfType)
|
||||
}
|
||||
|
||||
if (plink->type == JSON_LINK) {
|
||||
dbJLinkInit(plink, dbfType);
|
||||
dbJLinkInit(plink);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -131,7 +131,7 @@ void dbAddLink(struct dbLocker *locker, struct link *plink, short dbfType,
|
||||
* FIXME: Can't create DB links as dbJLink types yet,
|
||||
* dbLock.c doesn't have any way to find/track them.
|
||||
*/
|
||||
dbJLinkInit(plink, dbfType);
|
||||
dbJLinkInit(plink);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -2272,8 +2272,12 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
|
||||
|
||||
/* Check for braces => JSON */
|
||||
if (*str == '{' && str[len-1] == '}') {
|
||||
pinfo->ltype = JSON_LINK;
|
||||
return 0;
|
||||
long status = dbJLinkParse(str, len, ftype, &pinfo->jlink);
|
||||
|
||||
if (!status)
|
||||
pinfo->ltype = JSON_LINK;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Check for other HW link types */
|
||||
@@ -2428,8 +2432,10 @@ void dbSetLinkJSON(DBLINK *plink, dbLinkInfo *pinfo)
|
||||
{
|
||||
plink->type = JSON_LINK;
|
||||
plink->value.json.string = pinfo->target;
|
||||
plink->value.json.jlink = pinfo->jlink;
|
||||
|
||||
pinfo->target = NULL;
|
||||
pinfo->jlink = NULL;
|
||||
}
|
||||
|
||||
static
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#ifndef INCdbStaticPvth
|
||||
#define INCdbStaticPvth 1
|
||||
|
||||
#include "dbJLink.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@@ -40,15 +42,19 @@ typedef struct dbLinkInfo {
|
||||
short ltype;
|
||||
|
||||
/* full link string for CONSTANT and PV_LINK,
|
||||
* parm string for HW links*/
|
||||
* parm string for HW links, JSON for JSON_LINK
|
||||
*/
|
||||
char *target;
|
||||
|
||||
/* for PV_LINK */
|
||||
short modifiers;
|
||||
|
||||
/* HW links */
|
||||
/* for HW links */
|
||||
char hwid[6]; /* one extra element for a nil */
|
||||
int hwnums[5];
|
||||
|
||||
/* for JSON_LINK */
|
||||
jlink *jlink;
|
||||
} dbLinkInfo;
|
||||
|
||||
long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec);
|
||||
|
||||
@@ -80,7 +80,6 @@ static enum {
|
||||
/* define forward references*/
|
||||
static int checkDatabase(dbBase *pdbbase);
|
||||
static void initDrvSup(void);
|
||||
static void initJLinks(void);
|
||||
static void initRecSup(void);
|
||||
static void initDevSup(void);
|
||||
static void finishDevSup(void);
|
||||
@@ -147,7 +146,6 @@ static int iocBuild_2(void)
|
||||
{
|
||||
initHookAnnounce(initHookAfterCaLinkInit);
|
||||
|
||||
initJLinks();
|
||||
initDrvSup();
|
||||
initHookAnnounce(initHookAfterInitDrvSup);
|
||||
|
||||
@@ -377,22 +375,6 @@ static void initDrvSup(void) /* Locate all driver support entry tables */
|
||||
}
|
||||
}
|
||||
|
||||
static void initJLinks(void)
|
||||
{
|
||||
linkSup *plinkSup;
|
||||
|
||||
for (plinkSup = (linkSup *)ellFirst(&pdbbase->linkList); plinkSup;
|
||||
plinkSup = (linkSup *)ellNext(&plinkSup->node)) {
|
||||
jlif *pjlif = registryJLinkFind(plinkSup->name);
|
||||
|
||||
if (!pjlif) {
|
||||
errlogPrintf("iocInit: JLink %s not found\n", plinkSup->name);
|
||||
continue;
|
||||
}
|
||||
plinkSup->pjlif = pjlif;
|
||||
}
|
||||
}
|
||||
|
||||
static void initRecSup(void)
|
||||
{
|
||||
dbRecordType *pdbRecordType;
|
||||
|
||||
@@ -81,8 +81,7 @@ void registerJLinks(DBBASE *pbase, int nLinks, jlif * const *jlifsl)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nLinks; i++) {
|
||||
if (registryJLinkFind(jlifsl[i]->name)) continue;
|
||||
if (!registryJLinkAdd(jlifsl[i])) {
|
||||
if (!registryJLinkAdd(pbase, jlifsl[i])) {
|
||||
errlogPrintf("registryJLinkAdd failed %s\n",
|
||||
jlifsl[i]->name);
|
||||
continue;
|
||||
|
||||
@@ -1,27 +1,23 @@
|
||||
/*************************************************************************\
|
||||
* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
|
||||
* National Laboratory.
|
||||
* Copyright (c) 2002 The Regents of the University of California, as
|
||||
* Operator of Los Alamos National Laboratory.
|
||||
* EPICS BASE is distributed subject to a Software License Agreement found
|
||||
* in file LICENSE that is included with this distribution.
|
||||
\*************************************************************************/
|
||||
/* registryJLinks.c */
|
||||
|
||||
#define epicsExportSharedSymbols
|
||||
#include "registry.h"
|
||||
#define epicsExportSharedSymbols
|
||||
#include "dbBase.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "registryJLinks.h"
|
||||
#include "dbJLink.h"
|
||||
|
||||
static void *registryID = "JSON link types";
|
||||
|
||||
|
||||
epicsShareFunc int registryJLinkAdd(struct jlif *pjlif)
|
||||
epicsShareFunc int registryJLinkAdd(DBBASE *pbase, struct jlif *pjlif)
|
||||
{
|
||||
return registryAdd(registryID, pjlif->name, pjlif);
|
||||
}
|
||||
linkSup *plinkSup = dbFindLinkSup(pbase, pjlif->name);
|
||||
|
||||
epicsShareFunc jlif * registryJLinkFind(const char *name)
|
||||
{
|
||||
return registryFind(registryID, name);
|
||||
if (plinkSup)
|
||||
plinkSup->pjlif = pjlif;
|
||||
return !!plinkSup;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#ifndef INC_registryJLinks_H
|
||||
#define INC_registryJLinks_H
|
||||
|
||||
#include "dbBase.h"
|
||||
#include "dbJLink.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
@@ -17,8 +18,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
epicsShareFunc int registryJLinkAdd(jlif *pjlif);
|
||||
epicsShareFunc jlif * registryJLinkFind(const char *name);
|
||||
epicsShareFunc int registryJLinkAdd(DBBASE *pbase, jlif *pjlif);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ static lset lnkConst_lset;
|
||||
|
||||
/*************************** jlif Routines **************************/
|
||||
|
||||
static jlink* lnkConst_alloc(struct link *plink, short dbfType) {
|
||||
static jlink* lnkConst_alloc(short dbfType) {
|
||||
clink *clink = calloc(1, sizeof(struct clink));
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -275,9 +275,9 @@ static jlif_result lnkConst_end_array(jlink *pjlink) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static struct lset* lnkConst_get_lset(const jlink *pjlink) {
|
||||
static struct lset* lnkConst_get_lset(const jlink *pjlink, struct link *plink) {
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_get_lset(const@%p)\n", pjlink);
|
||||
printf("lnkConst_get_lset(const@%p, %p)\n", pjlink, plink);
|
||||
|
||||
return &lnkConst_lset;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user