Support "link(name, lset)" syntax in DBD files

Both Perl and dbStaticLib support included.
Also added a new std/link directory for link types.
Nothing looks up the registered link support tables yet.
This commit is contained in:
Andrew Johnson
2016-05-08 22:57:42 -05:00
parent 13294f80cc
commit 6a592dc2c0
17 changed files with 248 additions and 1 deletions

View File

@@ -44,6 +44,13 @@ typedef struct devSup {
struct dsxt *pdsxt; /* Extended device support */
}devSup;
typedef struct linkSup {
ELLNODE node;
char *name;
char *lset_name;
struct lset *lset;
} linkSup;
typedef struct dbDeviceMenu {
int nChoice;
char **papChoice;
@@ -162,6 +169,7 @@ typedef struct dbBase {
ELLLIST menuList;
ELLLIST recordTypeList;
ELLLIST drvList;
ELLLIST linkList;
ELLLIST registrarList;
ELLLIST functionList;
ELLLIST variableList;

View File

@@ -38,6 +38,7 @@ static int yyreset(void)
"field" return(tokenFIELD);
"device" return(tokenDEVICE);
"driver" return(tokenDRIVER);
"link" return(tokenLINK);
"breaktable" return(tokenBREAKTABLE);
"record" return(tokenRECORD);
"grecord" return(tokenGRECORD);

View File

@@ -75,6 +75,7 @@ static void dbRecordtypeFieldItem(char *name,char *value);
static void dbDevice(char *recordtype,char *linktype,
char *dsetname,char *choicestring);
static void dbDriver(char *name);
static void dbLinkType(char *name, char *lset_name);
static void dbRegistrar(char *name);
static void dbFunction(char *name);
static void dbVariable(char *name, char *type);
@@ -785,6 +786,26 @@ static void dbDriver(char *name)
ellAdd(&pdbbase->drvList,&pdrvSup->node);
}
static void dbLinkType(char *name, char *lset_name)
{
linkSup *pLinkSup;
GPHENTRY *pgphentry;
pgphentry = gphFind(pdbbase->pgpHash, name, &pdbbase->linkList);
if (pgphentry) {
return;
}
pLinkSup = dbCalloc(1,sizeof(linkSup));
pLinkSup->name = epicsStrDup(name);
pLinkSup->lset_name = epicsStrDup(lset_name);
pgphentry = gphAdd(pdbbase->pgpHash, pLinkSup->name, &pdbbase->linkList);
if (!pgphentry) {
yyerrorAbort("gphAdd failed");
}
pgphentry->userPvt = pLinkSup;
ellAdd(&pdbbase->linkList, &pLinkSup->node);
}
static void dbRegistrar(char *name)
{
dbText *ptext;

View File

@@ -86,6 +86,14 @@ static void dbDumpDriverCallFunc(const iocshArgBuf *args)
dbDumpDriver(*iocshPpdbbase);
}
/* dbDumpLink */
static const iocshArg * const dbDumpLinkArgs[] = { &argPdbbase};
static const iocshFuncDef dbDumpLinkFuncDef = {"dbDumpLink",1,dbDumpLinkArgs};
static void dbDumpLinkCallFunc(const iocshArgBuf *args)
{
dbDumpLink(*iocshPpdbbase);
}
/* dbDumpRegistrar */
static const iocshArg * const dbDumpRegistrarArgs[] = { &argPdbbase};
static const iocshFuncDef dbDumpRegistrarFuncDef = {"dbDumpRegistrar",1,dbDumpRegistrarArgs};
@@ -160,6 +168,7 @@ void dbStaticIocRegister(void)
iocshRegister(&dbDumpFieldFuncDef, dbDumpFieldCallFunc);
iocshRegister(&dbDumpDeviceFuncDef, dbDumpDeviceCallFunc);
iocshRegister(&dbDumpDriverFuncDef, dbDumpDriverCallFunc);
iocshRegister(&dbDumpLinkFuncDef, dbDumpLinkCallFunc);
iocshRegister(&dbDumpRegistrarFuncDef,dbDumpRegistrarCallFunc);
iocshRegister(&dbDumpFunctionFuncDef, dbDumpFunctionCallFunc);
iocshRegister(&dbDumpVariableFuncDef, dbDumpVariableCallFunc);

View File

@@ -458,6 +458,7 @@ void dbFreeBase(dbBase *pdbbase)
dbVariableDef *pvarNext;
drvSup *pdrvSup;
drvSup *pdrvSupNext;
linkSup *plinkSup;
brkTable *pbrkTable;
brkTable *pbrkTableNext;
chFilterPlugin *pfilt;
@@ -558,6 +559,11 @@ void dbFreeBase(dbBase *pdbbase)
free((void *)pdrvSup);
pdrvSup = pdrvSupNext;
}
while ((plinkSup = (linkSup *) ellGet(&pdbbase->linkList))) {
free(plinkSup->lset_name);
free(plinkSup->name);
free(plinkSup);
}
ptext = (dbText *)ellFirst(&pdbbase->registrarList);
while(ptext) {
ptextNext = (dbText *)ellNext(&ptext->node);
@@ -1070,6 +1076,21 @@ long dbWriteDriverFP(DBBASE *pdbbase,FILE *fp)
return(0);
}
long dbWriteLinkFP(DBBASE *pdbbase, FILE *fp)
{
linkSup *plinkSup;
if (!pdbbase) {
fprintf(stderr, "pdbbase not specified\n");
return -1;
}
for (plinkSup = (linkSup *) ellFirst(&pdbbase->linkList);
plinkSup; plinkSup = (linkSup *) ellNext(&plinkSup->node)) {
fprintf(fp, "link(%s,%s)\n", plinkSup->name, plinkSup->lset_name);
}
return 0;
}
long dbWriteRegistrarFP(DBBASE *pdbbase,FILE *fp)
{
dbText *ptext;
@@ -3107,6 +3128,12 @@ char * dbGetRelatedField(DBENTRY *psave)
return(rtnval);
}
linkSup* dbFindLinkSup(dbBase *pdbbase, const char *name) {
GPHENTRY *pgph = gphFind(pdbbase->pgpHash,name,&pdbbase->linkList);
if (!pgph) return NULL;
return (linkSup *) pgph->userPvt;
}
int dbGetNLinks(DBENTRY *pdbentry)
{
dbRecordType *precordType = pdbentry->precordType;
@@ -3460,6 +3487,15 @@ void dbDumpDriver(DBBASE *pdbbase)
dbWriteDriverFP(pdbbase,stdout);
}
void dbDumpLink(DBBASE *pdbbase)
{
if(!pdbbase) {
fprintf(stderr,"pdbbase not specified\n");
return;
}
dbWriteLinkFP(pdbbase,stdout);
}
void dbDumpRegistrar(DBBASE *pdbbase)
{
if(!pdbbase) {

View File

@@ -99,6 +99,7 @@ epicsShareFunc long dbWriteDeviceFP(DBBASE *pdbbase, FILE *fp);
epicsShareFunc long dbWriteDriver(DBBASE *pdbbase,
const char *filename);
epicsShareFunc long dbWriteDriverFP(DBBASE *pdbbase, FILE *fp);
epicsShareFunc long dbWriteLinkFP(DBBASE *pdbbase, FILE *fp);
epicsShareFunc long dbWriteRegistrarFP(DBBASE *pdbbase, FILE *fp);
epicsShareFunc long dbWriteFunctionFP(DBBASE *pdbbase, FILE *fp);
epicsShareFunc long dbWriteVariableFP(DBBASE *pdbbase, FILE *fp);
@@ -208,6 +209,9 @@ epicsShareFunc drvSup * dbFindDriver(dbBase *pdbbase,
const char *name);
epicsShareFunc char * dbGetRelatedField(DBENTRY *pdbentry);
epicsShareFunc linkSup * dbFindLinkSup(dbBase *pdbbase,
const char *name);
epicsShareFunc int dbGetNLinks(DBENTRY *pdbentry);
epicsShareFunc long dbGetLinkField(DBENTRY *pdbentry, int index);
epicsShareFunc int dbGetLinkType(DBENTRY *pdbentry);
@@ -227,6 +231,7 @@ epicsShareFunc void dbDumpField(DBBASE *pdbbase,
epicsShareFunc void dbDumpDevice(DBBASE *pdbbase,
const char *recordTypeName);
epicsShareFunc void dbDumpDriver(DBBASE *pdbbase);
epicsShareFunc void dbDumpLink(DBBASE *pdbbase);
epicsShareFunc void dbDumpRegistrar(DBBASE *pdbbase);
epicsShareFunc void dbDumpFunction(DBBASE *pdbbase);
epicsShareFunc void dbDumpVariable(DBBASE *pdbbase);

View File

@@ -20,7 +20,7 @@ static int yyAbort = 0;
%token tokenINCLUDE tokenPATH tokenADDPATH
%token tokenALIAS tokenMENU tokenCHOICE tokenRECORDTYPE
%token tokenFIELD tokenINFO tokenREGISTRAR
%token tokenDEVICE tokenDRIVER tokenBREAKTABLE
%token tokenDEVICE tokenDRIVER tokenLINK tokenBREAKTABLE
%token tokenRECORD tokenGRECORD tokenVARIABLE tokenFUNCTION
%token <Str> tokenSTRING tokenCDEFS
@@ -46,6 +46,7 @@ database_item: include
| tokenRECORDTYPE recordtype_head recordtype_body
| device
| driver
| link
| registrar
| function
| variable
@@ -162,6 +163,13 @@ driver: tokenDRIVER '(' tokenSTRING ')'
dbDriver($3); dbmfFree($3);
};
link: tokenLINK '(' tokenSTRING ',' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("link %s %s\n",$3,$5);
dbLinkType($3,$5);
dbmfFree($3); dbmfFree($5);
};
registrar: tokenREGISTRAR '(' tokenSTRING ')'
{
if(dbStaticDebug>2) printf("registrar %s\n",$3);

View File

@@ -20,6 +20,7 @@ dbRecStd_RCS += dbRecStd.rc
include $(STDDIR)/rec/Makefile
include $(STDDIR)/dev/Makefile
include $(STDDIR)/filters/Makefile
include $(STDDIR)/link/Makefile
include $(STDDIR)/softIoc/Makefile
include $(TOP)/configure/RULES

17
src/std/link/Makefile Normal file
View File

@@ -0,0 +1,17 @@
#*************************************************************************
# 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.
#*************************************************************************
# This is a Makefile fragment, see src/std/Makefile.
SRC_DIRS += $(STDDIR)/link
DBD += links.dbd
# dbRecStd_SRCS += ...
HTMLS += links.html

View File

@@ -0,0 +1,92 @@
=head1 Link Types
Links are an extensible mechanism for adding new kinds of database link,
using JSON for link addresses.
The following link types are available in this release:
=over
=item * L<Constant|/"Constant Link const">
=item * L<Database|/"Database Link db">
=item * L<Channel Access|/"Channel Access Link ca">
=back
=head2 Using Links
...
must appear inside a pair of braces C< {} > expressed as a JSON
(L<JavaScript Object Notation|http://www.json.org/>) object, which allows link
parameters to be defined as needed.
Note that due to the required presence of the double-quote characters in the
JSON strings in a link field value string in a database file, it will usually
be necessary to escape all double-quote characters in the JSON object by
preceding them with a backslash C< \ > character.
Database configuration tools that support this link mechanism must be careful
to handle these escapes correctly on reading and writing string values from/to
a .db file.
=head2 Filter Reference
=cut
link(const,lsetConst)
=head3 Constant Link C<"const">
...
=head4 Parameters
...
=head4 Example
...
=cut
link(db,lsetDatabase)
=head3 Database Link C<"db">
...
=head4 Parameters
...
=head4 Example
...
=cut
link(ca,lsetChannelAccess)
=head3 Channel Access Link C<"ca">
...
=head4 Parameters
...
=over
=item ...
...
=back
...
=head4 Example
...
=cut

View File

@@ -9,8 +9,10 @@
softIoc.dbd$(DEP): $(COMMON_DIR)/stdRecords.dbd
softIoc.dbd$(DEP): $(COMMON_DIR)/filters.dbd
softIoc.dbd$(DEP): $(COMMON_DIR)/links.dbd
$(COMMON_DIR)/softIoc.dbd: $(COMMON_DIR)/stdRecords.dbd
$(COMMON_DIR)/softIoc.dbd: $(COMMON_DIR)/filters.dbd
$(COMMON_DIR)/softIoc.dbd: $(COMMON_DIR)/links.dbd
$(COMMON_DIR)/softIoc.dbd: $(STDDIR)/softIoc/Makefile
softMain$(DEP): epicsInstallDir.h

View File

@@ -16,6 +16,9 @@ include "stdRecords.dbd"
# Channel filters & plugins
include "filters.dbd"
# Link types
include "links.dbd"
# Standard device support
include "devSoft.dbd"

View File

@@ -6,6 +6,7 @@ use warnings;
use DBD::Base;
use DBD::Breaktable;
use DBD::Driver;
use DBD::Link;
use DBD::Menu;
use DBD::Recordtype;
use DBD::Recfield;
@@ -21,6 +22,7 @@ sub new {
my $this = {
'DBD::Breaktable' => {},
'DBD::Driver' => {},
'DBD::Link' => {},
'DBD::Function' => {},
'DBD::Menu' => {},
'DBD::Recordtype' => {},
@@ -80,6 +82,10 @@ sub drivers {
return shift->{'DBD::Driver'};
}
sub links {
return shift->{'DBD::Link'};
}
sub functions {
return shift->{'DBD::Function'};
}

22
src/tools/DBD/Link.pm Normal file
View File

@@ -0,0 +1,22 @@
package DBD::Link;
use DBD::Base;
@ISA = qw(DBD::Base);
sub init {
my ($this, $name, $lset) = @_;
$this->SUPER::init($lset, "link support (lset)");
$this->{KEY} = $name;
return $this;
}
sub key {
return shift->{KEY};
}
sub equals {
my ($a, $b) = @_;
return $a->SUPER::equals($b)
&& $a->{KEY} eq $b->{KEY};
}
1;

View File

@@ -13,6 +13,7 @@ use DBD::Base;
use DBD::Breaktable;
use DBD::Device;
use DBD::Driver;
use DBD::Link;
use DBD::Menu;
use DBD::Recordtype;
use DBD::Recfield;
@@ -26,6 +27,7 @@ sub OutputDBD {
OutputMenus($out, $dbd->menus);
OutputRecordtypes($out, $dbd->recordtypes);
OutputDrivers($out, $dbd->drivers);
OutputLinks($out, $dbd->links);
OutputRegistrars($out, $dbd->registrars);
OutputFunctions($out, $dbd->functions);
OutputVariables($out, $dbd->variables);
@@ -78,6 +80,13 @@ sub OutputDrivers {
foreach keys %{$drivers};
}
sub OutputLinks {
my ($out, $links) = @_;
while (my ($name, $link) = each %{$links}) {
printf $out "link(%s, %s)\n", $link->key, $name;
}
}
sub OutputRegistrars {
my ($out, $registrars) = @_;
printf $out "registrar(%s)\n", $_

View File

@@ -13,6 +13,7 @@ use DBD::Base;
use DBD::Breaktable;
use DBD::Device;
use DBD::Driver;
use DBD::Link;
use DBD::Menu;
use DBD::Recordtype;
use DBD::Recfield;
@@ -37,6 +38,11 @@ sub ParseDBD {
my ($driver_name) = unquote($1);
$dbd->add(DBD::Driver->new($driver_name));
}
elsif (m/\G link \s* \( \s* $RXstr \s*, \s* $RXstr \s* \)/oxgc) {
print "Link $1, $2\n" if $debug;
my ($key, $lset) = unquote($1, $2);
$dbd->add(DBD::Link->new($key, $lset));
}
elsif (m/\G registrar \s* \( \s* $RXstr \s* \)/oxgc) {
print "Registrar: $1\n" if $debug;
my ($registrar_name) = unquote($1);

View File

@@ -23,6 +23,7 @@ PERL_MODULES += DBD/Base.pm
PERL_MODULES += DBD/Breaktable.pm
PERL_MODULES += DBD/Device.pm
PERL_MODULES += DBD/Driver.pm
PERL_MODULES += DBD/Link.pm
PERL_MODULES += DBD/Function.pm
PERL_MODULES += DBD/Menu.pm
PERL_MODULES += DBD/Output.pm