From 3992d4b92ad6ee0493af6e7ba1609cde980d3fc3 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 1 Sep 2016 00:56:26 -0500 Subject: [PATCH] Split dbJLinkInit, JLinks are now parsed at load-time --- src/ioc/db/dbJLink.c | 50 ++++++++++++++++++++----------- src/ioc/db/dbJLink.h | 8 +++-- src/ioc/db/dbLink.c | 4 +-- src/ioc/dbStatic/dbStaticLib.c | 10 +++++-- src/ioc/dbStatic/dbStaticPvt.h | 10 +++++-- src/ioc/misc/iocInit.c | 18 ----------- src/ioc/registry/registryCommon.c | 3 +- src/ioc/registry/registryJLinks.c | 20 +++++-------- src/ioc/registry/registryJLinks.h | 4 +-- src/std/link/lnkConst.c | 6 ++-- 10 files changed, 70 insertions(+), 63 deletions(-) diff --git a/src/ioc/db/dbJLink.c b/src/ioc/db/dbJLink.c index 40797e9d8..f94a90e17 100644 --- a/src/ioc/db/dbJLink.c +++ b/src/ioc/db/dbJLink.c @@ -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; +} diff --git a/src/ioc/db/dbJLink.h b/src/ioc/db/dbJLink.h index 503b64af8..fc3d86005 100644 --- a/src/ioc/db/dbJLink.h +++ b/src/ioc/db/dbJLink.h @@ -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 } diff --git a/src/ioc/db/dbLink.c b/src/ioc/db/dbLink.c index 78df46941..2f2bd461a 100644 --- a/src/ioc/db/dbLink.c +++ b/src/ioc/db/dbLink.c @@ -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; } diff --git a/src/ioc/dbStatic/dbStaticLib.c b/src/ioc/dbStatic/dbStaticLib.c index b9532516b..a1a62e652 100644 --- a/src/ioc/dbStatic/dbStaticLib.c +++ b/src/ioc/dbStatic/dbStaticLib.c @@ -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 diff --git a/src/ioc/dbStatic/dbStaticPvt.h b/src/ioc/dbStatic/dbStaticPvt.h index 8e58e9535..3e2435e79 100644 --- a/src/ioc/dbStatic/dbStaticPvt.h +++ b/src/ioc/dbStatic/dbStaticPvt.h @@ -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); diff --git a/src/ioc/misc/iocInit.c b/src/ioc/misc/iocInit.c index 09558c1fb..f863e3fe9 100644 --- a/src/ioc/misc/iocInit.c +++ b/src/ioc/misc/iocInit.c @@ -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; diff --git a/src/ioc/registry/registryCommon.c b/src/ioc/registry/registryCommon.c index f4ec4af55..56664c5bb 100644 --- a/src/ioc/registry/registryCommon.c +++ b/src/ioc/registry/registryCommon.c @@ -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; diff --git a/src/ioc/registry/registryJLinks.c b/src/ioc/registry/registryJLinks.c index 04c827098..921a2cbcc 100644 --- a/src/ioc/registry/registryJLinks.c +++ b/src/ioc/registry/registryJLinks.c @@ -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; } diff --git a/src/ioc/registry/registryJLinks.h b/src/ioc/registry/registryJLinks.h index 3f304c6d5..7e6a8933e 100644 --- a/src/ioc/registry/registryJLinks.h +++ b/src/ioc/registry/registryJLinks.h @@ -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 } diff --git a/src/std/link/lnkConst.c b/src/std/link/lnkConst.c index 842867b6d..14d8a5b59 100644 --- a/src/std/link/lnkConst.c +++ b/src/std/link/lnkConst.c @@ -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; }