jlink conditional debug print
Enable magic info("linkDebug","YES") to enable
debug prints during parsing.
This commit is contained in:
@@ -1006,7 +1006,7 @@ static long dbPutFieldLink(DBADDR *paddr,
|
||||
return S_db_badDbrtype;
|
||||
}
|
||||
|
||||
status = dbParseLink(pstring, pfldDes->field_type, &link_info);
|
||||
status = dbParseLink(pstring, pfldDes->field_type, &link_info, 0);
|
||||
if (status)
|
||||
return status;
|
||||
|
||||
|
||||
@@ -18,24 +18,15 @@
|
||||
#define epicsExportSharedSymbols
|
||||
#include "dbAccessDefs.h"
|
||||
#include "dbCommon.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "dbStaticPvt.h"
|
||||
#include "dbLink.h"
|
||||
#include "dbJLink.h"
|
||||
#include "dbLock.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "link.h"
|
||||
|
||||
/* Change 'undef' to 'define' to turn on debug statements: */
|
||||
#undef DEBUG_JLINK
|
||||
|
||||
#ifdef DEBUG_JLINK
|
||||
int jlinkDebug = 10;
|
||||
# define IFDEBUG(n) \
|
||||
if (jlinkDebug >= n) /* block or statement */
|
||||
#else
|
||||
# define IFDEBUG(n) \
|
||||
if(0) /* Compiler will elide the block or statement */
|
||||
#endif
|
||||
|
||||
#define IFDEBUG(n) if(parser->debug)
|
||||
|
||||
typedef struct parseContext {
|
||||
jlink *pjlink;
|
||||
@@ -43,6 +34,7 @@ typedef struct parseContext {
|
||||
short dbfType;
|
||||
short jsonDepth;
|
||||
unsigned key_is_link:1;
|
||||
unsigned debug:1;
|
||||
} parseContext;
|
||||
|
||||
#define CALL_OR_STOP(routine) !(routine) ? jlif_stop : (routine)
|
||||
@@ -51,9 +43,9 @@ static int dbjl_return(parseContext *parser, jlif_result result) {
|
||||
jlink *pjlink = parser->pjlink;
|
||||
|
||||
IFDEBUG(10) {
|
||||
printf("dbjl_return(%s@%p, %d)\t", pjlink->pif->name, pjlink, result);
|
||||
printf("dbjl_return(%s@%p, %d)\t", pjlink ? pjlink->pif->name : "", pjlink, result);
|
||||
printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n",
|
||||
parser->jsonDepth, pjlink->parseDepth, parser->key_is_link);
|
||||
parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link);
|
||||
}
|
||||
|
||||
if (result == jlif_stop && pjlink) {
|
||||
@@ -74,19 +66,21 @@ static int dbjl_value(parseContext *parser, jlif_result result) {
|
||||
jlink *parent;
|
||||
|
||||
IFDEBUG(10) {
|
||||
printf("dbjl_value(%s@%p, %d)\t", pjlink->pif->name, pjlink, result);
|
||||
printf("dbjl_value(%s@%p, %d)\t", pjlink ? pjlink->pif->name : "", pjlink, result);
|
||||
printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n",
|
||||
parser->jsonDepth, pjlink->parseDepth, parser->key_is_link);
|
||||
parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link);
|
||||
}
|
||||
|
||||
if (result == jlif_stop || pjlink->parseDepth > 0)
|
||||
return dbjl_return(parser, result);
|
||||
|
||||
parent = pjlink->parent;
|
||||
if (!parent)
|
||||
if (!parent) {
|
||||
parser->product = pjlink;
|
||||
else if (parent->pif->end_child)
|
||||
} else if (parent->pif->end_child) {
|
||||
parent->pif->end_child(parent, pjlink);
|
||||
}
|
||||
pjlink->debug = 0;
|
||||
|
||||
parser->pjlink = parent;
|
||||
|
||||
@@ -101,7 +95,7 @@ static int dbjl_null(void *ctx) {
|
||||
jlink *pjlink = parser->pjlink;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("dbjl_null(%s@%p)\n", pjlink->pif->name, pjlink);
|
||||
printf("dbjl_null(%s@%p)\n", pjlink ? pjlink->pif->name : "", pjlink);
|
||||
|
||||
assert(pjlink);
|
||||
return dbjl_value(parser,
|
||||
@@ -175,9 +169,9 @@ static int dbjl_start_map(void *ctx) {
|
||||
}
|
||||
|
||||
IFDEBUG(10) {
|
||||
printf("dbjl_start_map(%s@%p)\t", pjlink->pif->name, pjlink);
|
||||
printf("dbjl_start_map(%s@%p)\t", pjlink ? pjlink->pif->name : "", pjlink);
|
||||
printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n",
|
||||
parser->jsonDepth, pjlink->parseDepth, parser->key_is_link);
|
||||
parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link);
|
||||
}
|
||||
|
||||
pjlink->parseDepth++;
|
||||
@@ -213,7 +207,7 @@ static int dbjl_map_key(void *ctx, const unsigned char *key, unsigned len) {
|
||||
printf("dbjl_map_key(%s@%p, \"%.*s\")\t",
|
||||
pjlink->pif->name, pjlink, len, key);
|
||||
printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n",
|
||||
parser->jsonDepth, pjlink->parseDepth, parser->key_is_link);
|
||||
parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link);
|
||||
}
|
||||
|
||||
assert(pjlink->parseDepth > 0);
|
||||
@@ -256,6 +250,7 @@ static int dbjl_map_key(void *ctx, const unsigned char *key, unsigned len) {
|
||||
pjlink->pif = pjlif;
|
||||
pjlink->parent = NULL;
|
||||
pjlink->parseDepth = 0;
|
||||
pjlink->debug = !!parser->debug;
|
||||
|
||||
if (parser->pjlink) {
|
||||
/* We're starting a child link, save its parent */
|
||||
@@ -265,7 +260,7 @@ static int dbjl_map_key(void *ctx, const unsigned char *key, unsigned len) {
|
||||
parser->key_is_link = 0;
|
||||
|
||||
IFDEBUG(8)
|
||||
printf("dbjl_map_key: New %s@%p\n", pjlink->pif->name, pjlink);
|
||||
printf("dbjl_map_key: New %s@%p\n", pjlink ? pjlink->pif->name : "", pjlink);
|
||||
|
||||
return jlif_continue;
|
||||
}
|
||||
@@ -301,9 +296,9 @@ static int dbjl_start_array(void *ctx) {
|
||||
jlink *pjlink = parser->pjlink;
|
||||
|
||||
IFDEBUG(10) {
|
||||
printf("dbjl_start_array(%s@%p)\t", pjlink->pif->name, pjlink);
|
||||
printf("dbjl_start_array(%s@%p)\t", pjlink ? pjlink->pif->name : "", pjlink);
|
||||
printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n",
|
||||
parser->jsonDepth, pjlink->parseDepth, parser->key_is_link);
|
||||
parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link);
|
||||
}
|
||||
|
||||
assert(pjlink);
|
||||
@@ -319,9 +314,9 @@ static int dbjl_end_array(void *ctx) {
|
||||
jlink *pjlink = parser->pjlink;
|
||||
|
||||
IFDEBUG(10) {
|
||||
printf("dbjl_end_array(%s@%p)\t", pjlink->pif->name, pjlink);
|
||||
printf("dbjl_end_array(%s@%p)\t", pjlink ? pjlink->pif->name : "", pjlink);
|
||||
printf(" jsonDepth=%d, parseDepth=%d, key_is_link=%d\n",
|
||||
parser->jsonDepth, pjlink->parseDepth, parser->key_is_link);
|
||||
parser->jsonDepth, pjlink ? pjlink->parseDepth : 0, parser->key_is_link);
|
||||
}
|
||||
|
||||
assert(pjlink);
|
||||
@@ -342,7 +337,7 @@ static const yajl_parser_config dbjl_config =
|
||||
{ 0, 0 }; /* allowComments = NO, checkUTF8 = NO */
|
||||
|
||||
long dbJLinkParse(const char *json, size_t jlen, short dbfType,
|
||||
jlink **ppjlink)
|
||||
jlink **ppjlink, unsigned opts)
|
||||
{
|
||||
parseContext context, *parser = &context;
|
||||
yajl_alloc_funcs dbjl_allocs;
|
||||
@@ -350,15 +345,16 @@ long dbJLinkParse(const char *json, size_t jlen, short dbfType,
|
||||
yajl_status ys;
|
||||
long status;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("dbJLinkInit(\"%.*s\", %d, %p)\n",
|
||||
(int) jlen, json, dbfType, ppjlink);
|
||||
|
||||
parser->pjlink = NULL;
|
||||
parser->product = NULL;
|
||||
parser->dbfType = dbfType;
|
||||
parser->jsonDepth = 0;
|
||||
parser->key_is_link = 0;
|
||||
parser->debug = !!(opts&LINK_DEBUG);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("dbJLinkInit(\"%.*s\", %d, %p)\n",
|
||||
(int) jlen, json, dbfType, ppjlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("dbJLinkInit: jsonDepth=%d, key_is_link=%d\n",
|
||||
|
||||
@@ -35,6 +35,7 @@ typedef struct jlink {
|
||||
struct jlif *pif; /* Link methods */
|
||||
struct jlink *parent; /* NULL for top-level links */
|
||||
int parseDepth; /* Used by parser, unused afterwards */
|
||||
unsigned debug:1; /* set by caller of jlif operations to request debug output to console */
|
||||
/* Link types extend or embed this structure for private storage */
|
||||
} jlink;
|
||||
|
||||
@@ -112,7 +113,7 @@ typedef struct jlif {
|
||||
} jlif;
|
||||
|
||||
epicsShareFunc long dbJLinkParse(const char *json, size_t len, short dbfType,
|
||||
jlink **ppjlink);
|
||||
jlink **ppjlink, unsigned opts);
|
||||
epicsShareFunc long dbJLinkInit(struct link *plink);
|
||||
|
||||
epicsShareFunc void dbJLinkFree(jlink *);
|
||||
|
||||
@@ -86,7 +86,7 @@ static void testLinkParse(void)
|
||||
for (;td->str; td++) {
|
||||
int i, N;
|
||||
testDiag("Parsing \"%s\"", td->str);
|
||||
testOk(dbParseLink(td->str, DBF_INLINK, &info) == 0, "Parser returned OK");
|
||||
testOk(dbParseLink(td->str, DBF_INLINK, &info, 0) == 0, "Parser returned OK");
|
||||
if (!testOk(info.ltype == td->info.ltype, "Link type value"))
|
||||
testDiag("Expected %d, got %d", td->info.ltype, info.ltype);
|
||||
if (td->info.target)
|
||||
@@ -146,7 +146,7 @@ static void testLinkFailParse(void)
|
||||
eltc(1);
|
||||
|
||||
for(;*td; td++) {
|
||||
testOk(dbParseLink(*td, DBF_INLINK, &info) == S_dbLib_badField,
|
||||
testOk(dbParseLink(*td, DBF_INLINK, &info, 0) == S_dbLib_badField,
|
||||
"dbParseLink correctly rejected \"%s\"", *td);
|
||||
}
|
||||
|
||||
|
||||
@@ -2175,7 +2175,7 @@ long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec)
|
||||
if(!plink->text)
|
||||
continue;
|
||||
|
||||
if(dbParseLink(plink->text, pflddes->field_type, &link_info)!=0) {
|
||||
if(dbParseLink(plink->text, pflddes->field_type, &link_info, 0)!=0) {
|
||||
/* This was already parsed once when ->text was set.
|
||||
* Any syntax error messages were printed at that time.
|
||||
*/
|
||||
@@ -2204,7 +2204,7 @@ void dbFreeLinkInfo(dbLinkInfo *pinfo)
|
||||
pinfo->target = NULL;
|
||||
}
|
||||
|
||||
long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
|
||||
long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, unsigned opts)
|
||||
{
|
||||
char *pstr;
|
||||
size_t len;
|
||||
@@ -2240,7 +2240,7 @@ long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo)
|
||||
|
||||
/* Check for braces => JSON */
|
||||
if (*str == '{' && str[len-1] == '}') {
|
||||
if (dbJLinkParse(str, len, ftype, &pinfo->jlink))
|
||||
if (dbJLinkParse(str, len, ftype, &pinfo->jlink, opts))
|
||||
goto fail;
|
||||
|
||||
pinfo->ltype = JSON_LINK;
|
||||
@@ -2573,8 +2573,19 @@ long dbPutString(DBENTRY *pdbentry,const char *pstring)
|
||||
case DBF_FWDLINK: {
|
||||
dbLinkInfo link_info;
|
||||
DBLINK *plink = (DBLINK *)pfield;
|
||||
DBENTRY infoentry;
|
||||
unsigned opts = 0;
|
||||
|
||||
status = dbParseLink(pstring, pflddes->field_type, &link_info);
|
||||
if(pdbentry->precnode && ellCount(&pdbentry->precnode->infoList)) {
|
||||
dbCopyEntryContents(pdbentry, &infoentry);
|
||||
|
||||
if(dbFindInfo(&infoentry, "linkDebug")==0 && epicsStrCaseCmp(dbGetInfoString(&infoentry), "YES")==0)
|
||||
opts |= LINK_DEBUG;
|
||||
|
||||
dbFinishEntry(&infoentry);
|
||||
}
|
||||
|
||||
status = dbParseLink(pstring, pflddes->field_type, &link_info, opts);
|
||||
if (status) break;
|
||||
|
||||
if (plink->type==CONSTANT && plink->value.constantStr==NULL) {
|
||||
|
||||
@@ -59,10 +59,12 @@ typedef struct dbLinkInfo {
|
||||
|
||||
long dbInitRecordLinks(dbRecordType *rtyp, struct dbCommon *prec);
|
||||
|
||||
#define LINK_DEBUG 1
|
||||
|
||||
/* Parse link string. no record locks needed.
|
||||
* on success caller must free pinfo->target
|
||||
*/
|
||||
epicsShareFunc long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo);
|
||||
epicsShareFunc long dbParseLink(const char *str, short ftype, dbLinkInfo *pinfo, unsigned opts);
|
||||
/* Check if link type allow the parsed link value pinfo
|
||||
* to be assigned to the given link.
|
||||
* Record containing plink must be locked.
|
||||
|
||||
Reference in New Issue
Block a user