dbJLink: Handle NULL returned by jlif::alloc() better

It might not mean out-of-memory, adjust error message.
Add OOM and dbfType error checks to all jlif::alloc() routines.

Change all IFDEBUG() in JLink types to use exported global variables.
This allows debug messages to be output from the jlif::alloc()
routines, since the jlink field isn't set when they're called.
This commit is contained in:
Andrew Johnson
2018-01-20 19:50:33 -06:00
parent c0d4835e66
commit 5e394e4928
5 changed files with 84 additions and 42 deletions

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* dbJLink.c */
@@ -241,25 +241,29 @@ static int dbjl_map_key(void *ctx, const unsigned char *key, size_t len) {
return dbjl_return(parser, jlif_stop);
}
dbmfFree(link_name);
pjlink = pjlif->alloc_jlink(parser->dbfType);
if (!pjlink) {
errlogPrintf("dbJLinkInit: Out of memory\n");
errlogPrintf("dbJLinkInit: Link type '%s' allocation failed. \n",
link_name);
dbmfFree(link_name);
return dbjl_return(parser, jlif_stop);
}
pjlink->pif = pjlif;
pjlink->parent = NULL;
pjlink->parseDepth = 0;
pjlink->debug = !!parser->lset_debug;
if (parser->pjlink) {
/* We're starting a child link, save its parent */
pjlink->parent = parser->pjlink;
}
else
pjlink->parent = NULL;
parser->pjlink = pjlink;
parser->key_is_link = 0;
dbmfFree(link_name);
IFDEBUG(8)
printf("dbjl_map_key: New %s@%p\n", pjlink ? pjlink->pif->name : "", pjlink);

View File

@@ -33,15 +33,17 @@ database file syntax.
=cut
link(const, lnkConstIf)
variable(lnkConst_debug, int)
=head3 Constant Link C<"const">
Constant links provide one or more values at link initalization time, but do not
return any data when their C<getValue()> routine is called. Most record types
support the use of constant links by calling C<recGblInitConstantLink()> at
record initialization, which results in the constant value being loaded into the
target field at that time.
Constant links are input links that provide literal values at link initalization
time, but do not return any data when their C<getValue()> routine is called.
Most record types support the use of constant links on their input links by
calling C<recGblInitConstantLink()> at record initialization, which results in
the constant value being loaded into the target field at that time.
Note that for most record types (the C<printf> and C<calcout> records are the
main exceptions) it is pointless to set an input link to a constant link at
@@ -72,14 +74,16 @@ converted to the desired double value at initialization, for example:
=cut
link(calc, lnkCalcIf)
variable(lnkCalc_debug, int)
=head3 Calculation Link C<"calc">
Calculation links can perform simple mathematical expressions on scalar
(double-precision floating-point) values obtained from other link types and
return a single double-precision floating-point result. The expressions are
evaluated by the EPICS Calc engine, and up to 12 inputs can be provided.
Calculation links are input links that can evaluate mathematical expressions on
scalar (double- precision floating-point) values obtained from child links, and
return a double-precision floating-point result. The expressions are evaluated
by the EPICS Calc engine, and up to 12 inputs can be provided.
=head4 Parameters
@@ -132,13 +136,15 @@ atomically with the value of the input argument.
=cut
link(state, lnkStateIf)
variable(lnkState_debug, int)
=head3 dbState Link C<"state">
A dbState link is one that reads or writes a boolean value from/to a named
global flag as implemented by the dbState facility in C<dbstate.h>. The link
type can invert the sense of the dbState flag if desired.
A dbState link is one that gets or puts a boolean value from/to a named global
flag as implemented by the dbState facility in C<dbstate.h>. The link type can
invert the sense of the dbState flag during the get or put if desired.
The value of the named flag is read or written at the time of the link I/O
operation. When reading a flag, the value returned by the link will be zero or
@@ -156,10 +162,10 @@ mechanism.
=head4 Parameters
The link address must be a string providing the name of the dbState object, with
an optional leading C<!> charater to indicate the flag's value should be
inverted. The dbState object will be created when the link is initialized if it
doesn't already exist.
The link takes a single parameter which must be a string, providing the name of
the dbState object, with an optional leading C<!> character to indicate that the
flag's value should be inverted. The dbState object will be created when the
link is initialized if it doesn't already exist.
=head4 Examples

View File

@@ -40,7 +40,10 @@
typedef long (*FASTCONVERT)();
#define IFDEBUG(n) if(clink->jlink.debug)
int lnkCalc_debug;
epicsExportAddress(int, lnkCalc_debug);
#define IFDEBUG(n) if (lnkCalc_debug >= (n))
typedef struct calc_link {
jlink jlink; /* embedded object */
@@ -77,10 +80,21 @@ static lset lnkCalc_lset;
static jlink* lnkCalc_alloc(short dbfType)
{
calc_link *clink = calloc(1, sizeof(struct calc_link));
calc_link *clink;
IFDEBUG(10)
printf("lnkCalc_alloc()\n");
printf("lnkCalc_alloc(%d)\n", dbfType);
if (dbfType != DBF_INLINK) {
errlogPrintf("lnkCalc: Only works with input links\n");
return NULL;
}
clink = calloc(1, sizeof(struct calc_link));
if (!clink) {
errlogPrintf("lnkCalc: calloc() failed.\n");
return NULL;
}
clink->nArgs = 0;
clink->pstate = ps_init;
@@ -355,8 +369,6 @@ static void lnkCalc_end_child(jlink *parent, jlink *child)
static struct lset* lnkCalc_get_lset(const jlink *pjlink)
{
calc_link *clink = CONTAINER(pjlink, struct calc_link, jlink);
IFDEBUG(10)
printf("lnkCalc_get_lset(calc@%p)\n", pjlink);

View File

@@ -2,7 +2,7 @@
* Copyright (c) 2016 UChicago Argonne LLC, as Operator of Argonne
* National Laboratory.
* EPICS BASE is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
* in file LICENSE that is included with this distribution.
\*************************************************************************/
/* lnkConst.c */
@@ -22,7 +22,10 @@
#include "epicsExport.h"
#define IFDEBUG(n) if (clink->jlink.debug)
int lnkConst_debug;
epicsExportAddress(int, lnkConst_debug);
#define IFDEBUG(n) if (lnkConst_debug >= (n))
typedef long (*FASTCONVERT)();
@@ -48,10 +51,21 @@ static lset lnkConst_lset;
static jlink* lnkConst_alloc(short dbfType)
{
const_link *clink = calloc(1, sizeof(*clink));
const_link *clink;
IFDEBUG(10)
printf("lnkConst_alloc()\n");
printf("lnkConst_alloc(%d)\n", dbfType);
if (dbfType != DBF_INLINK) {
errlogPrintf("lnkConst: Only works with input links\n");
return NULL;
}
clink = calloc(1, sizeof(*clink));
if (!clink) {
errlogPrintf("lnkConst: calloc() failed.\n");
return NULL;
}
clink->type = s0;
clink->nElems = 0;
@@ -146,7 +160,6 @@ static jlif_result lnkConst_integer(jlink *pjlink, long long num)
static jlif_result lnkConst_boolean(jlink *pjlink, int val)
{
const_link *clink = CONTAINER(pjlink, const_link, jlink);
IFDEBUG(10)
printf("lnkConst_boolean(const@%p, %d)\n", pjlink, val);
@@ -276,8 +289,6 @@ static jlif_result lnkConst_start_array(jlink *pjlink)
static jlif_result lnkConst_end_array(jlink *pjlink)
{
const_link *clink = CONTAINER(pjlink, const_link, jlink);
IFDEBUG(10)
printf("lnkConst_end_array(const@%p)\n", pjlink);
@@ -286,8 +297,6 @@ static jlif_result lnkConst_end_array(jlink *pjlink)
static struct lset* lnkConst_get_lset(const jlink *pjlink)
{
const_link *clink = CONTAINER(pjlink, const_link, jlink);
IFDEBUG(10)
printf("lnkConst_get_lset(const@%p)\n", pjlink);
@@ -629,4 +638,3 @@ static jlif lnkConstIf = {
lnkConst_report, NULL
};
epicsExportAddress(jlif, lnkConstIf);

View File

@@ -35,7 +35,10 @@
typedef long (*FASTCONVERT)();
#define IFDEBUG(n) if(slink->jlink.debug)
int lnkState_debug;
epicsExportAddress(int, lnkState_debug);
#define IFDEBUG(n) if (lnkState_debug >= (n))
typedef struct state_link {
jlink jlink; /* embedded object */
@@ -52,10 +55,21 @@ static lset lnkState_lset;
static jlink* lnkState_alloc(short dbfType)
{
state_link *slink = calloc(1, sizeof(struct state_link));
state_link *slink;
IFDEBUG(10)
printf("lnkState_alloc()\n");
printf("lnkState_alloc(%d)\n", dbfType);
if (dbfType == DBF_FWDLINK) {
errlogPrintf("lnkState: DBF_FWDLINK not supported\n");
return NULL;
}
slink = calloc(1, sizeof(struct state_link));
if (!slink) {
errlogPrintf("lnkState: calloc() failed.\n");
return NULL;
}
slink->name = NULL;
slink->state = NULL;
@@ -97,8 +111,6 @@ static jlif_result lnkState_string(jlink *pjlink, const char *val, size_t len)
static struct lset* lnkState_get_lset(const jlink *pjlink)
{
state_link *slink = CONTAINER(pjlink, struct state_link, jlink);
IFDEBUG(10)
printf("lnkState_get_lset(state@%p)\n", pjlink);