diff --git a/src/dbStatic/dbBase.h b/src/dbStatic/dbBase.h index f32a3532f..b63239632 100644 --- a/src/dbStatic/dbBase.h +++ b/src/dbStatic/dbBase.h @@ -152,7 +152,8 @@ typedef struct dbBase { ELLLIST recordTypeList; ELLLIST drvList; ELLLIST registrarList; - ELLLIST variableList; + ELLLIST functionList; + ELLLIST variableList; ELLLIST bptList; /*Break Point Table Head*/ void *pathPvt; void *ppvd; /* pointer to process variable directory*/ diff --git a/src/dbStatic/dbExpand.c b/src/dbStatic/dbExpand.c index 76b8027ca..da7b3bedc 100644 --- a/src/dbStatic/dbExpand.c +++ b/src/dbStatic/dbExpand.c @@ -111,6 +111,7 @@ int main(int argc,char **argv) dbWriteDeviceFP(pdbbase,outFP); dbWriteDriverFP(pdbbase,outFP); dbWriteRegistrarFP(pdbbase,outFP); + dbWriteFunctionFP(pdbbase,outFP); dbWriteVariableFP(pdbbase,outFP); dbWriteBreaktableFP(pdbbase,outFP); dbWriteRecordFP(pdbbase,outFP,0,0); diff --git a/src/dbStatic/dbLex.l b/src/dbStatic/dbLex.l index dde726a9c..1bc0108c5 100644 --- a/src/dbStatic/dbLex.l +++ b/src/dbStatic/dbLex.l @@ -41,7 +41,8 @@ static int yyreset(void) "grecord" return(tokenGRECORD); "info" return(tokenINFO); "registrar" return(tokenREGISTRAR); -"variable" return(tokenVARIABLE); +"function" return(tokenFUNCTION); +"variable" return(tokenVARIABLE); [0-9]+ { /*integer number*/ yylval.Str = (char *)dbmfMalloc(strlen(yytext)+1); diff --git a/src/dbStatic/dbLexRoutines.c b/src/dbStatic/dbLexRoutines.c index 69ac52280..04ecb3d72 100644 --- a/src/dbStatic/dbLexRoutines.c +++ b/src/dbStatic/dbLexRoutines.c @@ -64,6 +64,7 @@ static void dbDevice(char *recordtype,char *linktype, char *dsetname,char *choicestring); static void dbDriver(char *name); static void dbRegistrar(char *name); +static void dbFunction(char *name); static void dbVariable(char *name, char *type); static void dbBreakHead(char *name); @@ -760,6 +761,25 @@ static void dbRegistrar(char *name) ellAdd(&pdbbase->registrarList,&ptext->node); } +static void dbFunction(char *name) +{ + dbText *ptext; + GPHENTRY *pgphentry; + + pgphentry = gphFind(pdbbase->pgpHash,name,&pdbbase->functionList); + if(pgphentry) { + return; + } + ptext = dbCalloc(1,sizeof(dbText)); + ptext->text = epicsStrDup(name); + pgphentry = gphAdd(pdbbase->pgpHash,ptext->text,&pdbbase->functionList); + if(!pgphentry) { + yyerrorAbort("gphAdd failed"); + } + pgphentry->userPvt = ptext; + ellAdd(&pdbbase->functionList,&ptext->node); +} + static void dbVariable(char *name, char *type) { dbVariableDef *pvar; diff --git a/src/dbStatic/dbStaticLib.c b/src/dbStatic/dbStaticLib.c index b55235927..1e29631e3 100644 --- a/src/dbStatic/dbStaticLib.c +++ b/src/dbStatic/dbStaticLib.c @@ -545,6 +545,7 @@ dbBase * epicsShareAPI dbAllocBase(void) ellInit(&pdbbase->recordTypeList); ellInit(&pdbbase->drvList); ellInit(&pdbbase->registrarList); + ellInit(&pdbbase->functionList); ellInit(&pdbbase->variableList); ellInit(&pdbbase->bptList); gphInitPvt(&pdbbase->pgpHash,256); @@ -675,6 +676,14 @@ void epicsShareAPI dbFreeBase(dbBase *pdbbase) free((void *)ptext); ptext = ptextNext; } + ptext = (dbText *)ellFirst(&pdbbase->functionList); + while(ptext) { + ptextNext = (dbText *)ellNext(&ptext->node); + ellDelete(&pdbbase->functionList,&ptext->node); + free((void *)ptext->text); + free((void *)ptext); + ptext = ptextNext; + } pvar = (dbVariableDef *)ellFirst(&pdbbase->variableList); while(pvar) { pvarNext = (dbVariableDef *)ellNext(&pvar->node); @@ -1175,6 +1184,21 @@ long epicsShareAPI dbWriteRegistrarFP(DBBASE *pdbbase,FILE *fp) return(0); } +long epicsShareAPI dbWriteFunctionFP(DBBASE *pdbbase,FILE *fp) +{ + dbText *ptext; + + if(!pdbbase) { + fprintf(stderr,"pdbbase not specified\n"); + return(-1); + } + for(ptext = (dbText *)ellFirst(&pdbbase->functionList); + ptext; ptext = (dbText *)ellNext(&ptext->node)) { + fprintf(fp,"function(%s)\n",ptext->text); + } + return(0); +} + long epicsShareAPI dbWriteVariableFP(DBBASE *pdbbase,FILE *fp) { dbVariableDef *pvar; @@ -3794,6 +3818,15 @@ void epicsShareAPI dbDumpRegistrar(DBBASE *pdbbase) dbWriteRegistrarFP(pdbbase,stdout); } +void epicsShareAPI dbDumpFunction(DBBASE *pdbbase) +{ + if(!pdbbase) { + printf("pdbbase not specified\n"); + return; + } + dbWriteFunctionFP(pdbbase,stdout); +} + void epicsShareAPI dbDumpVariable(DBBASE *pdbbase) { if(!pdbbase) { diff --git a/src/dbStatic/dbStaticLib.h b/src/dbStatic/dbStaticLib.h index ac9219ffb..33caeea8f 100644 --- a/src/dbStatic/dbStaticLib.h +++ b/src/dbStatic/dbStaticLib.h @@ -100,6 +100,7 @@ epicsShareFunc long epicsShareAPI dbWriteDriver( DBBASE *pdbbase,const char *filename); epicsShareFunc long epicsShareAPI dbWriteDriverFP(DBBASE *pdbbase,FILE *fp); epicsShareFunc long epicsShareAPI dbWriteRegistrarFP(DBBASE *pdbbase,FILE *fp); +epicsShareFunc long epicsShareAPI dbWriteFunctionFP(DBBASE *pdbbase,FILE *fp); epicsShareFunc long epicsShareAPI dbWriteVariableFP(DBBASE *pdbbase,FILE *fp); epicsShareFunc long epicsShareAPI dbWriteBreaktable( DBBASE *pdbbase,const char *filename); @@ -216,6 +217,7 @@ epicsShareFunc void epicsShareAPI dbDumpDevice( DBBASE *pdbbase,const char *recordTypeName); epicsShareFunc void epicsShareAPI dbDumpDriver(DBBASE *pdbbase); epicsShareFunc void epicsShareAPI dbDumpRegistrar(DBBASE *pdbbase); +epicsShareFunc void epicsShareAPI dbDumpFunction(DBBASE *pdbbase); epicsShareFunc void epicsShareAPI dbDumpVariable(DBBASE *pdbbase); epicsShareFunc void epicsShareAPI dbDumpBreaktable( DBBASE *pdbbase,const char *name); diff --git a/src/dbStatic/dbYacc.y b/src/dbStatic/dbYacc.y index 64ac8b9ef..fe882ae48 100644 --- a/src/dbStatic/dbYacc.y +++ b/src/dbStatic/dbYacc.y @@ -22,7 +22,7 @@ static int yyAbort = 0; %token tokenMENU tokenCHOICE tokenRECORDTYPE %token tokenFIELD tokenINFO tokenREGISTRAR %token tokenDEVICE tokenDRIVER tokenBREAKTABLE -%token tokenRECORD tokenGRECORD tokenVARIABLE +%token tokenRECORD tokenGRECORD tokenVARIABLE tokenFUNCTION %token tokenSTRING tokenCDEFS %union @@ -42,7 +42,8 @@ database_item: include | device | driver | registrar - | variable + | function + | variable | tokenBREAKTABLE break_head break_body | tokenRECORD record_head record_body | tokenGRECORD grecord_head record_body @@ -156,6 +157,12 @@ registrar: tokenREGISTRAR '(' tokenSTRING ')' dbRegistrar($3); dbmfFree($3); }; +function: tokenFUNCTION '(' tokenSTRING ')' +{ + if(dbStaticDebug>2) printf("function %s\n",$3); + dbFunction($3); dbmfFree($3); +}; + variable: tokenVARIABLE '(' tokenSTRING ')' { if(dbStaticDebug>2) printf("variable %s\n",$3); diff --git a/src/iocsh/Makefile b/src/iocsh/Makefile index 27b8fbdff..d6e8e0612 100644 --- a/src/iocsh/Makefile +++ b/src/iocsh/Makefile @@ -26,6 +26,7 @@ INC += iocshRegisterCommon.h INC += asTestRegister.h INC += envRegister.h INC += iocCoreLimitsRegister.h +INC += registryCommon.h INC += registryRegister.h @@ -50,6 +51,7 @@ LIBSRCS += envRegister.c LIBSRCS += iocUtil.c LIBSRCS += iocCoreLimitsRegister.c LIBSRCS += systemCommandRegister.c +LIBSRCS += registryCommon.c LIBSRCS += registryRegister.c LIBRARY_IOC = iocsh diff --git a/src/iocsh/dbStaticRegister.c b/src/iocsh/dbStaticRegister.c index 44fc74974..847a5ef41 100644 --- a/src/iocsh/dbStaticRegister.c +++ b/src/iocsh/dbStaticRegister.c @@ -106,6 +106,15 @@ static void dbDumpRegistrarCallFunc(const iocshArgBuf *args) dbDumpRegistrar(pdbbase); } +/* dbDumpFunction */ +static const iocshArg dbDumpFunctionArg0 = { "pdbbase",iocshArgPdbbase}; +static const iocshArg * const dbDumpFunctionArgs[1] = {&dbDumpFunctionArg0}; +static const iocshFuncDef dbDumpFunctionFuncDef = {"dbDumpFunction",1,dbDumpFunctionArgs}; +static void dbDumpFunctionCallFunc(const iocshArgBuf *args) +{ + dbDumpFunction(pdbbase); +} + /* dbDumpVariable */ static const iocshArg dbDumpVariableArg0 = { "pdbbase",iocshArgPdbbase}; static const iocshArg * const dbDumpVariableArgs[1] = {&dbDumpVariableArg0}; diff --git a/src/iocsh/registryCommon.c b/src/iocsh/registryCommon.c new file mode 100644 index 000000000..ef3bdd49a --- /dev/null +++ b/src/iocsh/registryCommon.c @@ -0,0 +1,87 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* registryCommon.c */ + +/* Author: Andrew Johnson + * Date: 2004-03-19 + */ + +#include +#include +#include +#include +#include + +#include "dbBase.h" +#include "shareLib.h" +#include "errlog.h" +#include "registryDeviceSupport.h" +#include "registryDriverSupport.h" + +#define epicsExportSharedSymbols +#include "registryCommon.h" + + +void epicsShareAPI registerRecordTypes(DBBASE *pbase, int nRecordTypes, + const char* const* recordTypeNames, const recordTypeLocation *rtl) +{ + int i; + for(i=0; i< nRecordTypes; i++) { + recordTypeLocation *precordTypeLocation; + computeSizeOffset sizeOffset; + DBENTRY dbEntry; + + if(registryRecordTypeFind(recordTypeNames[i])) continue; + if(!registryRecordTypeAdd(recordTypeNames[i],&rtl[i])) { + errlogPrintf("registryRecordTypeAdd failed %s\n", + recordTypeNames[i]); + continue; + } + dbInitEntry(pbase,&dbEntry); + precordTypeLocation = registryRecordTypeFind(recordTypeNames[i]); + sizeOffset = precordTypeLocation->sizeOffset; + if(dbFindRecordType(&dbEntry,recordTypeNames[i])) { + errlogPrintf("registerRecordDeviceDriver failed %s\n", + recordTypeNames[i]); + } else { + sizeOffset(dbEntry.precordType); + } + } +} + +void epicsShareAPI registerDevices(DBBASE *pbase, int nDevices, + const char* const* deviceSupportNames, const dset* const* devsl) +{ + int i; + for(i=0; i< nDevices; i++) { + if(registryDeviceSupportFind(deviceSupportNames[i])) continue; + if(!registryDeviceSupportAdd(deviceSupportNames[i],devsl[i])) { + errlogPrintf("registryDeviceSupportAdd failed %s\n", + deviceSupportNames[i]); + continue; + } + } +} + +void epicsShareAPI registerDrivers(DBBASE *pbase, int nDrivers, + const char* const* driverSupportNames, struct drvet* const* drvsl) +{ + int i; + for(i=0; i< nDrivers; i++) { + if(registryDriverSupportFind(driverSupportNames[i])) continue; + if(!registryDriverSupportAdd(driverSupportNames[i], drvsl[i])) { + errlogPrintf("registryDriverSupportAdd failed %s\n", + driverSupportNames[i]); + continue; + } + } +} + diff --git a/src/iocsh/registryCommon.h b/src/iocsh/registryCommon.h new file mode 100644 index 000000000..ff76f8141 --- /dev/null +++ b/src/iocsh/registryCommon.h @@ -0,0 +1,39 @@ +/*************************************************************************\ +* Copyright (c) 2002 The University of Chicago, as Operator of Argonne +* National Laboratory. +* Copyright (c) 2002 The Regents of the University of California, as +* Operator of Los Alamos National Laboratory. +* EPICS BASE Versions 3.13.7 +* and higher are distributed subject to a Software License Agreement found +* in file LICENSE that is included with this distribution. +\*************************************************************************/ + +/* registryCommon.h */ + +#include "dbBase.h" +#include "dbStaticLib.h" +#include "dbAccess.h" +#include "devSup.h" +#include "drvSup.h" +#include "recSup.h" +#include "registryRecordType.h" +#include "iocsh.h" +#include "shareLib.h" + +#ifdef __cplusplus +extern "C" { +#endif + +epicsShareFunc void epicsShareAPI registerRecordTypes( + DBBASE *pbase, int nRecordTypes, + const char* const* recordTypeNames, const recordTypeLocation *rtl); +epicsShareFunc void epicsShareAPI registerDevices( + DBBASE *pbase, int nDevices, + const char* const* deviceSupportNames, const dset* const* devsl); +epicsShareFunc void epicsShareAPI registerDrivers( + DBBASE *pbase, int nDrivers, + const char* const* driverSupportNames, struct drvet* const* drvsl); + +#ifdef __cplusplus +} +#endif diff --git a/src/libCom/misc/epicsExport.h b/src/libCom/misc/epicsExport.h index 11d768345..10df5f179 100644 --- a/src/libCom/misc/epicsExport.h +++ b/src/libCom/misc/epicsExport.h @@ -31,6 +31,11 @@ epicsShareDef typ *EPICS_EXPORT_POBJ(typ,obj) = (typ *)&obj #define epicsExportRegistrar(func) \ epicsShareFunc REGISTRAR EPICS_EXPORT_PFUNC(func) = (REGISTRAR)(void*)&func +#define epicsRegisterFunction(func) \ +static void register_func_ ## func(void) { \ + registryFunctionAdd(#func,(REGISTRYFUNCTION)func);} \ +epicsExportRegistrar(register_func_ ## func) + #ifdef __cplusplus } #endif diff --git a/src/registry/Makefile b/src/registry/Makefile index bd90b26b9..a8508c4c3 100644 --- a/src/registry/Makefile +++ b/src/registry/Makefile @@ -10,9 +10,6 @@ TOP=../.. include $(TOP)/configure/CONFIG -# includes to install from this sub-project -# - INC += registry.h INC += registryRecordType.h INC += registryDeviceSupport.h @@ -20,13 +17,6 @@ INC += registryDriverSupport.h INC += registryFunction.h -# general contents of library on all platforms -# -# system specific lines in RULES.Host figure out -# 1) what object names (.o, .obj,...) to build -# 2) where to find the sources: ., ./os/, ./os/generic, ... -# - SCRIPTS_HOST += registerRecordDeviceDriver.pl LIBSRCS += registry.c diff --git a/src/registry/registerRecordDeviceDriver.pl b/src/registry/registerRecordDeviceDriver.pl index 09203b3cd..4b383c508 100755 --- a/src/registry/registerRecordDeviceDriver.pl +++ b/src/registry/registerRecordDeviceDriver.pl @@ -14,57 +14,40 @@ eval 'exec perl -S $0 ${1+"$@"}' # -*- Mode: perl -*- $numberRecordType = 0; $numberDeviceSupport = 0; $numberDriverSupport = 0; -$numberRegistrar = 0; open(INP,"$file") or die "$! opening file"; while() { - next if /^\s*#/; - if (/\brecordtype\s*\(\s*(\w+)/) { + next if m/ ^ \s* \# /x; + if (m/ \b recordtype \s* \( \s* (\w+) \s* \) /x) { $recordType[$numberRecordType++] = $1; } - elsif (/\bdevice\s*\(\s*(\s*\w+)\W+\w+\W+(\w+)/) { + elsif (m/ \b device \s* \( \s* (\w+) \W+ \w+ \W+ (\w+) /x) { $deviceRecordType[$numberDeviceSupport] = $1; $deviceSupport[$numberDeviceSupport] = $2; $numberDeviceSupport++; } - elsif (/\bdriver\s*\(\s*(\w+)/) { + elsif (m/ \b driver \s* \( \s* (\w+) \s* \) /x) { $driverSupport[$numberDriverSupport++] = $1; } - elsif (/\bregistrar\s*\(\s*(\w+)/) { - $registrar[$numberRegistrar++] = $1; + elsif (m/ \b registrar \s* \( \s* (\w+) \s* \) /x) { + push @registrars, $1; } - elsif (/\bvariable\s*\(\s*(\w+)\s*,\s*(\w+)/) { + elsif (m/ \b function \s* \( \s* (\w+) \s* \) /x) { + push @registrars, "register_func_$1"; + } + elsif (m/ \b variable \s* \( \s* (\w+) \s* , \s* (\w+) \s* \) /x) { $varType{$1} = $2; push @variables, $1; } } close(INP) or die "$! closing file"; + + # beginning of generated routine - -print << "END" ; -/*#registerRecordDeviceDriver.cpp */ -/* THIS IS A GENERATED FILE. DO NOT EDIT */ -#include -#include -#include -#include -#include - -#include "dbBase.h" -#include "errlog.h" -#include "dbStaticLib.h" -#include "dbAccess.h" -#include "recSup.h" -#include "devSup.h" -#include "drvSup.h" -#include "registryRecordType.h" -#include "registryDeviceSupport.h" -#include "registryDriverSupport.h" -#include "iocsh.h" -#include "shareLib.h" -END - -print "extern \"C\" {\n"; +print "/* THIS IS A GENERATED FILE. DO NOT EDIT */\n", + "/* Generated from $file */\n\n", + "#include \"registryCommon.h\"\n\n", + "extern \"C\" {\n"; #definitions for recordtype if($numberRecordType>0) { @@ -134,9 +117,9 @@ if($numberDriverSupport>0) { } #definitions registrar -if($numberRegistrar>0) { - for ($i=0; $i<$numberRegistrar; $i++) { - print "epicsShareExtern void (*pvar_func_$registrar[$i])(void);\n"; +if(@registrars) { + foreach $reg (@registrars) { + print "epicsShareExtern void (*pvar_func_$reg)(void);\n"; } print "\n"; } @@ -161,73 +144,29 @@ if (@variables) { #Now actual registration code. -print << "END" ; -int $subname(DBBASE *pbase) -{ -END -if($numberRecordType>0 || $numberDeviceSupport>0 || $numberDriverSupport>0) { - print " int i;\n"; -} -if($numberRecordType>0) { - print << "END" ; - for(i=0; i< $numberRecordType; i++ ) { - recordTypeLocation *precordTypeLocation; - computeSizeOffset sizeOffset; - DBENTRY dbEntry; +print "int $subname(DBBASE *pbase)\n{\n"; - if(registryRecordTypeFind(recordTypeNames[i])) continue; - if(!registryRecordTypeAdd(recordTypeNames[i],&rtl[i])) { - errlogPrintf(\"registryRecordTypeAdd failed %s\\n\", - recordTypeNames[i]); - continue; - } - dbInitEntry(pbase,&dbEntry); - precordTypeLocation = registryRecordTypeFind(recordTypeNames[i]); - sizeOffset = precordTypeLocation->sizeOffset; - if(dbFindRecordType(&dbEntry,recordTypeNames[i])) { - errlogPrintf(\"registerRecordDeviceDriver failed %s\\n\", - recordTypeNames[i]); - } else { - sizeOffset(dbEntry.precordType); - } - } -END +if($numberRecordType>0) { + print " registerRecordTypes(pbase, $numberRecordType, ", + "recordTypeNames, rtl);\n"; } if($numberDeviceSupport>0) { - print << "END" ; - for(i=0; i< $numberDeviceSupport; i++ ) { - if(registryDeviceSupportFind(deviceSupportNames[i])) continue; - if(!registryDeviceSupportAdd(deviceSupportNames[i],devsl[i])) { - errlogPrintf(\"registryDeviceSupportAdd failed %s\\n\", - deviceSupportNames[i]); - continue; - } - } -END + print " registerDevices(pbase, $numberDeviceSupport, ", + "deviceSupportNames, devsl);\n"; } if($numberDriverSupport>0) { - print << "END" ; - for(i=0; i< $numberDriverSupport; i++ ) { - if(registryDriverSupportFind(driverSupportNames[i])) continue; - if(!registryDriverSupportAdd(driverSupportNames[i],drvsl[i])) { - errlogPrintf(\"registryDriverSupportAdd failed %s\\n\", - driverSupportNames[i]); - continue; - } - } -END + print " registerDrivers(pbase, $numberDriverSupport, ", + "driverSupportNames, drvsl);\n"; } -if($numberRegistrar>0) { - for($i=0; $i< $numberRegistrar; $i++ ) { - print " (*pvar_func_$registrar[$i])();\n"; - } +foreach $reg (@registrars) { + print " (*pvar_func_$reg)();\n"; } if (@variables) { print " iocshRegisterVariable(vardefs);\n"; } print << "END" ; - return(0); + return 0; } /* registerRecordDeviceDriver */ @@ -242,7 +181,7 @@ static void registerRecordDeviceDriverCallFunc(const iocshArgBuf *) $subname(pdbbase); } -} // ext C +} // extern "C" /* * Register commands on application startup */