Added JLink reporting infrastructure
Command 'dbjlr <record|*> <level>' calls the report method for all JSON links in all records, or in one named record. Added level and indent arguments to the jlif::report() method. Added jlif::map_children() method for recursing through all JSON links, plus dbJLinkMapChildren() and dbJLinkMapAll() APIs. Implemented the report and map_children methods in the const and calc link types.
This commit is contained in:
@@ -12,7 +12,6 @@
|
||||
|
||||
#include "alarm.h"
|
||||
#include "dbDefs.h"
|
||||
#include "dbmf.h"
|
||||
#include "errlog.h"
|
||||
#include "epicsAssert.h"
|
||||
#include "epicsString.h"
|
||||
@@ -56,6 +55,9 @@ typedef struct calc_link {
|
||||
epicsEnum16 stat;
|
||||
epicsEnum16 sevr;
|
||||
short prec;
|
||||
char *expr;
|
||||
char *major;
|
||||
char *minor;
|
||||
char *post_expr;
|
||||
char *post_major;
|
||||
char *post_minor;
|
||||
@@ -70,7 +72,8 @@ static lset lnkCalc_lset;
|
||||
|
||||
/*************************** jlif Routines **************************/
|
||||
|
||||
static jlink* lnkCalc_alloc(short dbfType) {
|
||||
static jlink* lnkCalc_alloc(short dbfType)
|
||||
{
|
||||
calc_link *clink = calloc(1, sizeof(struct calc_link));
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -86,7 +89,8 @@ static jlink* lnkCalc_alloc(short dbfType) {
|
||||
return &clink->jlink;
|
||||
}
|
||||
|
||||
static void lnkCalc_free(jlink *pjlink) {
|
||||
static void lnkCalc_free(jlink *pjlink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
int i;
|
||||
|
||||
@@ -96,6 +100,9 @@ static void lnkCalc_free(jlink *pjlink) {
|
||||
for (i = 0; i < clink->nArgs; i++)
|
||||
dbJLinkFree(clink->inp[i].value.json.jlink);
|
||||
|
||||
free(clink->expr);
|
||||
free(clink->major);
|
||||
free(clink->minor);
|
||||
free(clink->post_expr);
|
||||
free(clink->post_major);
|
||||
free(clink->post_minor);
|
||||
@@ -103,7 +110,8 @@ static void lnkCalc_free(jlink *pjlink) {
|
||||
free(clink);
|
||||
}
|
||||
|
||||
static jlif_result lnkCalc_integer(jlink *pjlink, long num) {
|
||||
static jlif_result lnkCalc_integer(jlink *pjlink, long num)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -130,7 +138,8 @@ static jlif_result lnkCalc_integer(jlink *pjlink, long num) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static jlif_result lnkCalc_double(jlink *pjlink, double num) {
|
||||
static jlif_result lnkCalc_double(jlink *pjlink, double num)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -152,7 +161,8 @@ static jlif_result lnkCalc_double(jlink *pjlink, double num) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static jlif_result lnkCalc_string(jlink *pjlink, const char *val, size_t len) {
|
||||
static jlif_result lnkCalc_string(jlink *pjlink, const char *val, size_t len)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
char *inbuf, *postbuf;
|
||||
short err;
|
||||
@@ -176,27 +186,32 @@ static jlif_result lnkCalc_string(jlink *pjlink, const char *val, size_t len) {
|
||||
return jlif_stop;
|
||||
}
|
||||
|
||||
if (clink->pstate == ps_major)
|
||||
clink->post_major = postbuf;
|
||||
else if (clink->pstate == ps_minor)
|
||||
clink->post_minor = postbuf;
|
||||
else
|
||||
clink->post_expr = postbuf;
|
||||
inbuf = epicsStrnDup(val, len);
|
||||
|
||||
inbuf = dbmfStrndup(val, len);
|
||||
if (clink->pstate == ps_major) {
|
||||
clink->major = inbuf;
|
||||
clink->post_major = postbuf;
|
||||
}
|
||||
else if (clink->pstate == ps_minor) {
|
||||
clink->minor = inbuf;
|
||||
clink->post_minor = postbuf;
|
||||
}
|
||||
else {
|
||||
clink->expr = inbuf;
|
||||
clink->post_expr = postbuf;
|
||||
}
|
||||
|
||||
if (postfix(inbuf, postbuf, &err) < 0) {
|
||||
errlogPrintf("lnkCalc: Error in calc expression, %s\n",
|
||||
calcErrorStr(err));
|
||||
dbmfFree(inbuf);
|
||||
return jlif_stop;
|
||||
}
|
||||
|
||||
dbmfFree(inbuf);
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static jlif_key_result lnkCalc_start_map(jlink *pjlink) {
|
||||
static jlif_key_result lnkCalc_start_map(jlink *pjlink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -213,7 +228,8 @@ static jlif_key_result lnkCalc_start_map(jlink *pjlink) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static jlif_result lnkCalc_map_key(jlink *pjlink, const char *key, size_t len) {
|
||||
static jlif_result lnkCalc_map_key(jlink *pjlink, const char *key, size_t len)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -251,7 +267,8 @@ static jlif_result lnkCalc_map_key(jlink *pjlink, const char *key, size_t len) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static jlif_result lnkCalc_end_map(jlink *pjlink) {
|
||||
static jlif_result lnkCalc_end_map(jlink *pjlink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -263,7 +280,8 @@ static jlif_result lnkCalc_end_map(jlink *pjlink) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static jlif_result lnkCalc_start_array(jlink *pjlink) {
|
||||
static jlif_result lnkCalc_start_array(jlink *pjlink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -277,7 +295,8 @@ static jlif_result lnkCalc_start_array(jlink *pjlink) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static jlif_result lnkCalc_end_array(jlink *pjlink) {
|
||||
static jlif_result lnkCalc_end_array(jlink *pjlink)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -289,7 +308,8 @@ static jlif_result lnkCalc_end_array(jlink *pjlink) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static void lnkCalc_end_child(jlink *parent, jlink *child) {
|
||||
static void lnkCalc_end_child(jlink *parent, jlink *child)
|
||||
{
|
||||
calc_link *clink = CONTAINER(parent, struct calc_link, jlink);
|
||||
struct link *plink;
|
||||
|
||||
@@ -307,20 +327,64 @@ static void lnkCalc_end_child(jlink *parent, jlink *child) {
|
||||
plink->value.json.jlink = child;
|
||||
}
|
||||
|
||||
static struct lset* lnkCalc_get_lset(const jlink *pjlink) {
|
||||
static struct lset* lnkCalc_get_lset(const jlink *pjlink)
|
||||
{
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_get_lset(calc@%p)\n", pjlink);
|
||||
|
||||
return &lnkCalc_lset;
|
||||
}
|
||||
|
||||
static void lnkCalc_report(const jlink *pjlink) {
|
||||
static void lnkCalc_report(const jlink *pjlink, int level, int indent)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
int i;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_report(calc@%p)\n", clink);
|
||||
|
||||
/* FIXME Implement! */
|
||||
printf("%*s'calc': \"%s\" = %.*g %s\n", indent, "",
|
||||
clink->expr, clink->prec, clink->val,
|
||||
clink->units ? clink->units : "");
|
||||
|
||||
if (level > 0) {
|
||||
if (clink->post_major)
|
||||
printf("%*s Major alarm: \"%s\"\n", indent, "",
|
||||
clink->major);
|
||||
if (clink->post_minor)
|
||||
printf("%*s Minor alarm: \"%s\"\n", indent, "",
|
||||
clink->minor);
|
||||
|
||||
for (i = 0; i < clink->nArgs; i++) {
|
||||
struct link *plink = &clink->inp[i];
|
||||
jlink *child = plink->type == JSON_LINK ?
|
||||
plink->value.json.jlink : NULL;
|
||||
|
||||
printf("%*s Input %c: %g\n", indent, "",
|
||||
i + 'A', clink->arg[i]);
|
||||
|
||||
if (child)
|
||||
dbJLinkReport(child, level - 1, indent + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long lnkCalc_map_children(jlink *pjlink, jlink_map_fn rtn, void *ctx)
|
||||
{
|
||||
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
|
||||
int i;
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkCalc_map_children(calc@%p)\n", clink);
|
||||
|
||||
for (i = 0; i < clink->nArgs; i++) {
|
||||
struct link *child = &clink->inp[i];
|
||||
long status = dbJLinkMapChildren(child, rtn, ctx);
|
||||
|
||||
if (status)
|
||||
return status;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************** lset Routines **************************/
|
||||
@@ -431,7 +495,7 @@ static long lnkCalc_getValue(struct link *plink, short dbrType, void *pbuffer,
|
||||
long nReq = 1;
|
||||
|
||||
dbGetLink(child, DBR_DOUBLE, &clink->arg[i], NULL, &nReq);
|
||||
/* FIXME Should we look at the return status from dbGetLink? */
|
||||
/* Any errors have already triggered a LINK/INVALID alarm */
|
||||
}
|
||||
clink->stat = 0;
|
||||
clink->sevr = 0;
|
||||
@@ -541,7 +605,8 @@ static jlif lnkCalcIf = {
|
||||
NULL, NULL, lnkCalc_integer, lnkCalc_double, lnkCalc_string,
|
||||
lnkCalc_start_map, lnkCalc_map_key, lnkCalc_end_map,
|
||||
lnkCalc_start_array, lnkCalc_end_array,
|
||||
lnkCalc_end_child, lnkCalc_get_lset, lnkCalc_report
|
||||
lnkCalc_end_child, lnkCalc_get_lset,
|
||||
lnkCalc_report, lnkCalc_map_children
|
||||
};
|
||||
epicsExportAddress(jlif, lnkCalcIf);
|
||||
|
||||
|
||||
@@ -56,7 +56,8 @@ static lset lnkConst_lset;
|
||||
|
||||
/*************************** jlif Routines **************************/
|
||||
|
||||
static jlink* lnkConst_alloc(short dbfType) {
|
||||
static jlink* lnkConst_alloc(short dbfType)
|
||||
{
|
||||
clink *clink = calloc(1, sizeof(struct clink));
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -72,7 +73,8 @@ static jlink* lnkConst_alloc(short dbfType) {
|
||||
return &clink->jlink;
|
||||
}
|
||||
|
||||
static void lnkConst_free(jlink *pjlink) {
|
||||
static void lnkConst_free(jlink *pjlink)
|
||||
{
|
||||
clink *clink = CONTAINER(pjlink, struct clink, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -93,7 +95,8 @@ static void lnkConst_free(jlink *pjlink) {
|
||||
free(clink);
|
||||
}
|
||||
|
||||
static jlif_result lnkConst_integer(jlink *pjlink, long num) {
|
||||
static jlif_result lnkConst_integer(jlink *pjlink, long num)
|
||||
{
|
||||
clink *clink = CONTAINER(pjlink, struct clink, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -145,7 +148,8 @@ static jlif_result lnkConst_boolean(jlink *pjlink, int val) {
|
||||
return lnkConst_integer(pjlink, val);
|
||||
}
|
||||
|
||||
static jlif_result lnkConst_double(jlink *pjlink, double num) {
|
||||
static jlif_result lnkConst_double(jlink *pjlink, double num)
|
||||
{
|
||||
clink *clink = CONTAINER(pjlink, struct clink, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -194,7 +198,8 @@ static jlif_result lnkConst_double(jlink *pjlink, double num) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static jlif_result lnkConst_string(jlink *pjlink, const char *val, size_t len) {
|
||||
static jlif_result lnkConst_string(jlink *pjlink, const char *val, size_t len)
|
||||
{
|
||||
clink *clink = CONTAINER(pjlink, struct clink, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -238,7 +243,8 @@ static jlif_result lnkConst_string(jlink *pjlink, const char *val, size_t len) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static jlif_result lnkConst_start_array(jlink *pjlink) {
|
||||
static jlif_result lnkConst_start_array(jlink *pjlink)
|
||||
{
|
||||
clink *clink = CONTAINER(pjlink, struct clink, jlink);
|
||||
|
||||
IFDEBUG(10)
|
||||
@@ -253,27 +259,104 @@ static jlif_result lnkConst_start_array(jlink *pjlink) {
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static jlif_result lnkConst_end_array(jlink *pjlink) {
|
||||
static jlif_result lnkConst_end_array(jlink *pjlink)
|
||||
{
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_end_array(const@%p)\n", pjlink);
|
||||
|
||||
return jlif_continue;
|
||||
}
|
||||
|
||||
static struct lset* lnkConst_get_lset(const jlink *pjlink) {
|
||||
static struct lset* lnkConst_get_lset(const jlink *pjlink)
|
||||
{
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_get_lset(const@%p)\n", pjlink);
|
||||
|
||||
return &lnkConst_lset;
|
||||
}
|
||||
|
||||
static void lnkConst_report(const jlink *pjlink) {
|
||||
|
||||
/* Report outputs:
|
||||
* 'const': integer 21
|
||||
* 'const': double 5.23
|
||||
* 'const': string "something"
|
||||
* 'const': array of 999 integers
|
||||
* [1, 2, 3]
|
||||
* 'const': array of 1 double
|
||||
* [1.2345]
|
||||
* 'const': array of 2 strings
|
||||
* ["hello", "world"]
|
||||
*
|
||||
* Array values are only printed at level 2
|
||||
* because there might be quite a few of them.
|
||||
*/
|
||||
|
||||
static void lnkConst_report(const jlink *pjlink, int level, int indent)
|
||||
{
|
||||
clink *clink = CONTAINER(pjlink, struct clink, jlink);
|
||||
const char * const type_names[4] = {
|
||||
"bug", "integer", "double", "string"
|
||||
};
|
||||
const char * const dtype = type_names[clink->type & 3];
|
||||
|
||||
IFDEBUG(10)
|
||||
printf("lnkConst_report(const@%p)\n", clink);
|
||||
|
||||
/* FIXME Implement! */
|
||||
if (clink->type > a0) {
|
||||
const char * const plural = clink->nElems > 1 ? "s" : "";
|
||||
|
||||
printf("%*s'const': array of %d %s%s", indent, "",
|
||||
clink->nElems, dtype, plural);
|
||||
|
||||
if (level < 2) {
|
||||
putchar('\n');
|
||||
}
|
||||
else {
|
||||
int i;
|
||||
|
||||
switch (clink->type) {
|
||||
case ai32:
|
||||
printf("\n%*s[%d", indent+2, "", clink->value.pintegers[0]);
|
||||
for (i = 1; i < clink->nElems; i++) {
|
||||
printf(", %d", clink->value.pintegers[i]);
|
||||
}
|
||||
break;
|
||||
case af64:
|
||||
printf("\n%*s[%g", indent+2, "", clink->value.pdoubles[0]);
|
||||
for (i = 1; i < clink->nElems; i++) {
|
||||
printf(", %g", clink->value.pdoubles[i]);
|
||||
}
|
||||
break;
|
||||
case ac40:
|
||||
printf("\n%*s[\"%s\"", indent+2, "", clink->value.pstrings[0]);
|
||||
for (i = 1; i < clink->nElems; i++) {
|
||||
printf(", \"%s\"", clink->value.pstrings[i]);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printf("]\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
printf("%*s'const': %s", indent, "", dtype);
|
||||
|
||||
switch (clink->type) {
|
||||
case si32:
|
||||
printf(" %d\n", clink->value.scalar_integer);
|
||||
return;
|
||||
case sf64:
|
||||
printf(" %g\n", clink->value.scalar_double);
|
||||
return;
|
||||
case sc40:
|
||||
printf(" \"%s\"\n", clink->value.scalar_string);
|
||||
return;
|
||||
default:
|
||||
printf(" -- type=%d\n", clink->type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*************************** lset Routines **************************/
|
||||
@@ -474,8 +557,10 @@ static lset lnkConst_lset = {
|
||||
static jlif lnkConstIf = {
|
||||
"const", lnkConst_alloc, lnkConst_free,
|
||||
NULL, lnkConst_boolean, lnkConst_integer, lnkConst_double, lnkConst_string,
|
||||
NULL, NULL, NULL, lnkConst_start_array, lnkConst_end_array,
|
||||
NULL, lnkConst_get_lset, lnkConst_report
|
||||
NULL, NULL, NULL,
|
||||
lnkConst_start_array, lnkConst_end_array,
|
||||
NULL, lnkConst_get_lset,
|
||||
lnkConst_report, NULL
|
||||
};
|
||||
epicsExportAddress(jlif, lnkConstIf);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user