jlink conditional debug print

Enable magic info("linkDebug","YES") to enable
debug prints during parsing.
This commit is contained in:
Michael Davidsaver
2017-04-27 19:46:33 -04:00
parent e51cc39b0c
commit 579a0791ea
6 changed files with 51 additions and 41 deletions

View File

@@ -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;

View File

@@ -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",

View File

@@ -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 *);

View File

@@ -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);
}

View File

@@ -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) {

View File

@@ -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.