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:
@@ -16,6 +16,7 @@
|
||||
#include "dbCaTest.h"
|
||||
#include "dbEvent.h"
|
||||
#include "dbIocRegister.h"
|
||||
#include "dbJLink.h"
|
||||
#include "dbLock.h"
|
||||
#include "dbNotify.h"
|
||||
#include "dbScan.h"
|
||||
@@ -109,6 +110,16 @@ static void dbcarCallFunc(const iocshArgBuf *args)
|
||||
dbcar(args[0].sval,args[1].ival);
|
||||
}
|
||||
|
||||
/* dbjlr */
|
||||
static const iocshArg dbjlrArg0 = { "record name",iocshArgString};
|
||||
static const iocshArg dbjlrArg1 = { "level",iocshArgInt};
|
||||
static const iocshArg * const dbjlrArgs[2] = {&dbjlrArg0,&dbjlrArg1};
|
||||
static const iocshFuncDef dbjlrFuncDef = {"dbjlr",2,dbjlrArgs};
|
||||
static void dbjlrCallFunc(const iocshArgBuf *args)
|
||||
{
|
||||
dbjlr(args[0].sval,args[1].ival);
|
||||
}
|
||||
|
||||
/* dbel */
|
||||
static const iocshArg dbelArg0 = { "record name",iocshArgString};
|
||||
static const iocshArg dbelArg1 = { "level",iocshArgInt};
|
||||
@@ -395,6 +406,7 @@ void dbIocRegister(void)
|
||||
iocshRegister(&dbsrFuncDef,dbsrCallFunc);
|
||||
iocshRegister(&dbcarFuncDef,dbcarCallFunc);
|
||||
iocshRegister(&dbelFuncDef,dbelCallFunc);
|
||||
iocshRegister(&dbjlrFuncDef,dbjlrCallFunc);
|
||||
|
||||
iocshRegister(&dbLoadDatabaseFuncDef,dbLoadDatabaseCallFunc);
|
||||
iocshRegister(&dbLoadRecordsFuncDef,dbLoadRecordsCallFunc);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "epicsAssert.h"
|
||||
#include "dbmf.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "errlog.h"
|
||||
#include "yajl_alloc.h"
|
||||
#include "yajl_parse.h"
|
||||
@@ -20,6 +21,7 @@
|
||||
#include "dbCommon.h"
|
||||
#include "dbLink.h"
|
||||
#include "dbJLink.h"
|
||||
#include "dbLock.h"
|
||||
#include "dbStaticLib.h"
|
||||
#include "link.h"
|
||||
|
||||
@@ -406,7 +408,133 @@ long dbJLinkInit(struct link *plink)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dbJLinkFree(jlink *pjlink) {
|
||||
void dbJLinkFree(jlink *pjlink)
|
||||
{
|
||||
if (pjlink)
|
||||
pjlink->pif->free_jlink(pjlink);
|
||||
}
|
||||
|
||||
void dbJLinkReport(jlink *pjlink, int level, int indent) {
|
||||
if (pjlink && pjlink->pif->report)
|
||||
pjlink->pif->report(pjlink, level, indent);
|
||||
}
|
||||
|
||||
long dbJLinkMapChildren(struct link *plink, jlink_map_fn rtn, void *ctx)
|
||||
{
|
||||
jlink *pjlink;
|
||||
long status;
|
||||
|
||||
if (!plink || plink->type != JSON_LINK)
|
||||
return 0;
|
||||
|
||||
pjlink = plink->value.json.jlink;
|
||||
if (!pjlink)
|
||||
return 0;
|
||||
|
||||
status = rtn(pjlink, ctx);
|
||||
if (!status && pjlink->pif->map_children)
|
||||
status = pjlink->pif->map_children(pjlink, rtn, ctx);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
long dbjlr(const char *recname, int level)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY * const pdbentry = &dbentry;
|
||||
long status;
|
||||
|
||||
if (!recname || recname[0] == '\0' || !strcmp(recname, "*")) {
|
||||
recname = NULL;
|
||||
printf("JSON links in all records\n\n");
|
||||
}
|
||||
else
|
||||
printf("JSON links in record '%s'\n\n", recname);
|
||||
|
||||
dbInitEntry(pdbbase, pdbentry);
|
||||
for (status = dbFirstRecordType(pdbentry);
|
||||
status == 0;
|
||||
status = dbNextRecordType(pdbentry)) {
|
||||
for (status = dbFirstRecord(pdbentry);
|
||||
status == 0;
|
||||
status = dbNextRecord(pdbentry)) {
|
||||
dbRecordType *pdbRecordType = pdbentry->precordType;
|
||||
dbCommon *precord = pdbentry->precnode->precord;
|
||||
char *prec = (char *) precord;
|
||||
int i;
|
||||
|
||||
if (recname && strcmp(recname, dbGetRecordName(pdbentry)))
|
||||
continue;
|
||||
if (dbIsAlias(pdbentry))
|
||||
continue;
|
||||
|
||||
printf(" %s record '%s':\n", pdbRecordType->name, precord->name);
|
||||
|
||||
dbScanLock(precord);
|
||||
for (i = 0; i < pdbRecordType->no_links; i++) {
|
||||
int idx = pdbRecordType->link_ind[i];
|
||||
dbFldDes *pdbFldDes = pdbRecordType->papFldDes[idx];
|
||||
DBLINK *plink = (DBLINK *) (prec + pdbFldDes->offset);
|
||||
|
||||
if (plink->type != JSON_LINK)
|
||||
continue;
|
||||
if (!dbLinkIsDefined(plink))
|
||||
continue;
|
||||
|
||||
printf(" Link field '%s':\n", pdbFldDes->name);
|
||||
dbJLinkReport(plink->value.json.jlink, level, 6);
|
||||
}
|
||||
dbScanUnlock(precord);
|
||||
if (recname)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
long dbJLinkMapAll(char *recname, jlink_map_fn rtn, void *ctx)
|
||||
{
|
||||
DBENTRY dbentry;
|
||||
DBENTRY * const pdbentry = &dbentry;
|
||||
long status;
|
||||
|
||||
if (recname && (recname[0] = '\0' || !strcmp(recname, "*")))
|
||||
recname = NULL;
|
||||
|
||||
dbInitEntry(pdbbase, pdbentry);
|
||||
for (status = dbFirstRecordType(pdbentry);
|
||||
status == 0;
|
||||
status = dbNextRecordType(pdbentry)) {
|
||||
for (status = dbFirstRecord(pdbentry);
|
||||
status == 0;
|
||||
status = dbNextRecord(pdbentry)) {
|
||||
dbRecordType *pdbRecordType = pdbentry->precordType;
|
||||
dbCommon *precord = pdbentry->precnode->precord;
|
||||
char *prec = (char *) precord;
|
||||
int i;
|
||||
|
||||
if (recname && strcmp(recname, dbGetRecordName(pdbentry)))
|
||||
continue;
|
||||
if (dbIsAlias(pdbentry))
|
||||
continue;
|
||||
|
||||
dbScanLock(precord);
|
||||
for (i = 0; i < pdbRecordType->no_links; i++) {
|
||||
int idx = pdbRecordType->link_ind[i];
|
||||
dbFldDes *pdbFldDes = pdbRecordType->papFldDes[idx];
|
||||
DBLINK *plink = (DBLINK *) (prec + pdbFldDes->offset);
|
||||
|
||||
status = dbJLinkMapChildren(plink, rtn, ctx);
|
||||
if (status)
|
||||
goto unlock;
|
||||
}
|
||||
unlock:
|
||||
dbScanUnlock(precord);
|
||||
if (status || recname)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
done:
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -32,29 +32,83 @@ struct lset;
|
||||
struct jlif;
|
||||
|
||||
typedef struct jlink {
|
||||
struct jlif *pif;
|
||||
struct jlink *parent;
|
||||
int parseDepth;
|
||||
struct jlif *pif; /* Link methods */
|
||||
struct jlink *parent; /* NULL for top-level links */
|
||||
int parseDepth; /* Used by parser, unused afterwards */
|
||||
/* Link types extend or embed this structure for private storage */
|
||||
} jlink;
|
||||
|
||||
typedef long (*jlink_map_fn)(jlink *, void *ctx);
|
||||
|
||||
typedef struct jlif {
|
||||
/* Optional parser methods below given as NULL are equivalent to
|
||||
* providing a routine that always returns jlif_stop, meaning that
|
||||
* this JSON construct is not allowed at this point in the parse.
|
||||
*/
|
||||
|
||||
const char *name;
|
||||
/* Name for the link type, used in link value */
|
||||
|
||||
jlink* (*alloc_jlink)(short dbfType);
|
||||
/* Required, allocate new link structure */
|
||||
|
||||
void (*free_jlink)(jlink *);
|
||||
/* Required, release all resources allocated for link */
|
||||
|
||||
jlif_result (*parse_null)(jlink *);
|
||||
/* Optional, parser saw a null value */
|
||||
|
||||
jlif_result (*parse_boolean)(jlink *, int val);
|
||||
/* Optional, parser saw a boolean value */
|
||||
|
||||
jlif_result (*parse_integer)(jlink *, long num);
|
||||
/* Optional, parser saw an integer value */
|
||||
|
||||
jlif_result (*parse_double)(jlink *, double num);
|
||||
/* Optional, parser saw a double value */
|
||||
|
||||
jlif_result (*parse_string)(jlink *, const char *val, size_t len);
|
||||
/* Optional, parser saw a string value */
|
||||
|
||||
jlif_key_result (*parse_start_map)(jlink *);
|
||||
/* Optional, parser saw an open-brace '{'. Return jlif_key_child_link
|
||||
* to expect a child link next (extra key/value pairs may follow).
|
||||
*/
|
||||
|
||||
jlif_result (*parse_map_key)(jlink *, const char *key, size_t len);
|
||||
/* Optional, parser saw a map key */
|
||||
|
||||
jlif_result (*parse_end_map)(jlink *);
|
||||
/* Optional, parser saw a close-brace '}' */
|
||||
|
||||
jlif_result (*parse_start_array)(jlink *);
|
||||
/* Optional, parser saw an open-bracket */
|
||||
|
||||
jlif_result (*parse_end_array)(jlink *);
|
||||
/* Optional, parser saw a close-bracket */
|
||||
|
||||
void (*end_child)(jlink *parent, jlink *child);
|
||||
/* Optional, called with pointer to the new child link after
|
||||
* parse_start_map() returned jlif_key_child_link */
|
||||
|
||||
struct lset* (*get_lset)(const jlink *);
|
||||
void (*report)(const jlink *);
|
||||
/* Required, return lset for this link instance */
|
||||
|
||||
void (*report)(const jlink *, int level, int indent);
|
||||
/* Optional, print status information about this link instance, then
|
||||
* if (level > 0) print a link identifier (at indent+2) and call
|
||||
* dbJLinkReport(child, level-1, indent+4)
|
||||
* for each child.
|
||||
*/
|
||||
|
||||
long (*map_children)(jlink *, jlink_map_fn rtn, void *ctx);
|
||||
/* Optional, call dbJLinkMapChildren() on all embedded links.
|
||||
* Stop immediately and return status if non-zero.
|
||||
*/
|
||||
|
||||
/* Link types must NOT extend this table with their own routines,
|
||||
* this space is reserved for extensions to the jlink interface.
|
||||
*/
|
||||
} jlif;
|
||||
|
||||
epicsShareFunc long dbJLinkParse(const char *json, size_t len, short dbfType,
|
||||
@@ -62,6 +116,13 @@ epicsShareFunc long dbJLinkParse(const char *json, size_t len, short dbfType,
|
||||
epicsShareFunc long dbJLinkInit(struct link *plink);
|
||||
|
||||
epicsShareFunc void dbJLinkFree(jlink *);
|
||||
epicsShareFunc void dbJLinkReport(jlink *, int level, int indent);
|
||||
|
||||
epicsShareFunc long dbJLinkMapChildren(struct link *,
|
||||
jlink_map_fn rtn, void *ctx);
|
||||
|
||||
epicsShareFunc long dbjlr(const char *recname, int level);
|
||||
epicsShareFunc long dbJLinkMapAll(char *recname, jlink_map_fn rtn, void *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -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