diff --git a/src/gdd/Makefile.Unix b/src/gdd/Makefile.Unix index b7a57ad79..68c10d4e9 100644 --- a/src/gdd/Makefile.Unix +++ b/src/gdd/Makefile.Unix @@ -5,6 +5,9 @@ # $Id$ # # $Log$ +# Revision 1.12 1996/10/14 16:33:36 jba +# Clean rule now uses rm macro. Removed . in VPATH def. +# # Revision 1.11 1996/07/24 22:47:29 jhill # removed OPTIM_YES=-g which caused link fail # @@ -66,7 +69,10 @@ INC += aitConvert.h INC += aitHelpers.h INC += dbMapper.h INC += gddAppTable.h -INC += gddAppFuncTable.h +# template class and inline member func +INC += gddAppFuncTable.h +# template member func (not "inline") +INC += gddAppFuncTable.cc INC += gddApps.h DEPENDS_RULE.cc = -$(COMPILE.cc) -xM $(SRCS.cc) >> .DEPENDS diff --git a/src/gdd/gddAppFuncTable.cc b/src/gdd/gddAppFuncTable.cc new file mode 100644 index 000000000..797a3a2d1 --- /dev/null +++ b/src/gdd/gddAppFuncTable.cc @@ -0,0 +1,211 @@ +/* + * $Id$ + * + * Author Jeffrey O. Hill + * johill@lanl.gov + * 505 665 1831 + * + * Experimental Physics and Industrial Control System (EPICS) + * + * Copyright 1991, the Regents of the University of California, + * and the University of Chicago Board of Governors. + * + * This software was produced under U.S. Government contracts: + * (W-7405-ENG-36) at the Los Alamos National Laboratory, + * and (W-31-109-ENG-38) at Argonne National Laboratory. + * + * Initial development by: + * The Controls and Automation Group (AT-8) + * Ground Test Accelerator + * Accelerator Technology Division + * Los Alamos National Laboratory + * + * Co-developed with + * The Controls and Computing Group + * Accelerator Systems Division + * Advanced Photon Source + * Argonne National Laboratory + * + * + * History + * $Log$ + * + */ + +#include + +// +// gddAppFuncTable::installReadFunc() +// +// The 2nd parameter has type "gddAppReadFunc" which is +// a ptr to member function. The member function should +// be declared as follows: +// +// gddAppFuncTableStatus PV::memberFunction(gdd &value); +// +// The typedef is not used here because of portability +// problems resulting from compiler weaknesses +// +template +gddAppFuncTableStatus gddAppFuncTable::installReadFunc( + const unsigned type, + gddAppFuncTableStatus (PV::*pMFuncIn)(gdd &value)) +{ + // + // Attempt to expand the table if the app type will not fit + // + if (type>=this->appTableNElem) { + this->newTbl(type); + if (type>=this->appTableNElem) { + return S_gddAppFuncTable_noMemory; + } + } + this->pMFuncRead[type]=pMFuncIn; + return S_gddAppFuncTable_Success; +} + +// +// installReadFunc() +// +// The 2nd parameter has type "gddAppReadFunc" which is +// a ptr to member function. The member function should +// be declared as follows: +// +// gddAppFuncTableStatus PV::memberFunction(gdd &value); +// +template +gddAppFuncTableStatus gddAppFuncTable::installReadFunc( + const char * const pName, + gddAppFuncTableStatus (PV::*pMFuncIn)(gdd &value)) +{ + aitUint32 type; + gddStatus rc; + + rc = gddApplicationTypeTable:: + app_table.registerApplicationType (pName, type); + if (rc!=0 && rc!=gddErrorAlreadyDefined) { + printf( +"at gdd lib limit => read of PV attribute \"%s\" will fail\n", pName); + return S_gddAppFuncTable_gddLimit; + } +# ifdef DEBUG + printf("installing PV attribute %s = %d\n", pName, type); +# endif + return this->installReadFunc(type, pMFuncIn); +} + +// +// gddAppFuncTable::newTbl() +// +// The total number of application tags to manage should be +// hidden from the application +// +// The typedef is not used here because of portability +// problems resulting from compiler weaknesses +// +template +void gddAppFuncTable::newTbl(unsigned newApplTypeMax) +{ + gddAppReadFunc *pMNewFuncTbl; + unsigned maxApp; + unsigned i; + + if (this->appTableNElem>newApplTypeMax) { + return; + } + maxApp = newApplTypeMax+(1u<<6u); +# ifdef _MSC_VER + // + // Right now all MS Visual C++ compilers allocate the + // wrong amount of memory (i.e. too little) + // for member function pointers, + // only explicit calculation via sizeof() works. + // For future versions this may become "if _MSC_VER < ???"... + // + pMNewFuncTbl = (gddAppReadFunc *) + new char[sizeof(gddAppReadFunc) * maxApp]; +# else + pMNewFuncTbl = new gddAppReadFunc[maxApp]; +# endif + if (pMNewFuncTbl) { + for (i=0u; iappTableNElem) { + pMNewFuncTbl[i] = this->pMFuncRead[i]; + } + else { + // + // some versions of NULL include (void *) cast + // (so I am using vanilla zero here) + // + pMNewFuncTbl[i] = 0; + } + } + if (this->pMFuncRead) { + delete [] this->pMFuncRead; + } + this->pMFuncRead = pMNewFuncTbl; + this->appTableNElem = maxApp; + } +} + + +// +// gddAppFuncTable::read() +// +template +gddAppFuncTableStatus gddAppFuncTable::read(PV &pv, gdd &value) +{ + gddAppFuncTableStatus status; + + // + // if this gdd is a container then step through it + // and fetch all of the values inside + // + if (value.isContainer()) { + gddContainer *pCont = (gddContainer *) &value; + gddCursor curs = pCont->getCursor(); + gdd *pItem; + + status = S_gddAppFuncTable_Success; + for (pItem=curs.first(); pItem; pItem=curs.next()) + { + status = this->read(pv, *pItem); + if (status) { + break; + } + } + return status; + } + return callReadFunc(pv, value); +} + +// +// gddAppFuncTable::callReadFunc() +// +template +gddAppFuncTableStatus gddAppFuncTable::callReadFunc (PV &pv, gdd &value) +{ + unsigned type = value.applicationType(); + gddAppReadFunc pFunc; + + // + // otherwise call the function associated + // with this application type + // + type = value.applicationType(); + if (type>=this->appTableNElem) { + errPrintf (S_gddAppFuncTable_badType, __FILE__, + __LINE__, "- large appl type code = %u\n", + type); + return S_gddAppFuncTable_badType; + } + pFunc = this->pMFuncRead[type]; + if (pFunc==NULL) { + errPrintf (S_gddAppFuncTable_badType, __FILE__, + __LINE__, "- ukn appl type code = %u\n", + type); + return S_gddAppFuncTable_badType; + } + return (pv.*pFunc)(value); +} + diff --git a/src/gdd/gddAppFuncTable.h b/src/gdd/gddAppFuncTable.h index 175744919..b6018a089 100644 --- a/src/gdd/gddAppFuncTable.h +++ b/src/gdd/gddAppFuncTable.h @@ -29,6 +29,9 @@ * * History * $Log$ + * Revision 1.3 1996/09/04 20:58:18 jhill + * changes for MS VISC++ + * * Revision 1.2 1996/08/13 23:13:35 jhill * win NT changes * @@ -44,6 +47,9 @@ * */ +#ifndef gddAppFuncTableH +#define gddAppFuncTableH + // // ANSI C // @@ -66,11 +72,17 @@ typedef aitUint32 gddAppFuncTableStatus; #define NELEMENTS(array) (sizeof(array)/sizeof((array)[0])) #endif +// +// template class gddAppFuncTable +// template class gddAppFuncTable { public: - gddAppFuncTable() : pMFuncRead(NULL), appTableNElem(0u) {} + gddAppFuncTable() : pMFuncRead(NULL), appTableNElem(0u) + { + } + ~gddAppFuncTable() { if (this->pMFuncRead) { @@ -85,44 +97,27 @@ public: // // installReadFunc() - // + // + // The 2nd parameter has type "gddAppReadFunc" which is + // a ptr to member function. The member function should + // be declared as follows: + // + // gddAppFuncTableStatus PV::memberFunction(gdd &value); + // gddAppFuncTableStatus installReadFunc(const unsigned type, - gddAppReadFunc pMFuncIn) - { - // - // Attempt to expand the table if the app type will not fit - // - if (type>=this->appTableNElem) { - this->newTbl(type); - if (type>=this->appTableNElem) { - return S_gddAppFuncTable_noMemory; - } - } - this->pMFuncRead[type]=pMFuncIn; - return S_gddAppFuncTable_Success; - } + gddAppReadFunc pMFuncIn); // // installReadFunc() - // + // + // The 2nd parameter has type "gddAppReadFunc" which is + // a ptr to member function. The member function should + // be declared as follows: + // + // gddAppFuncTableStatus PV::memberFunction(gdd &value); + // gddAppFuncTableStatus installReadFunc(const char * const pName, - gddAppReadFunc pMFuncIn) - { - aitUint32 type; - gddStatus rc; - - rc = gddApplicationTypeTable:: - app_table.registerApplicationType (pName, type); - if (rc!=0 && rc!=gddErrorAlreadyDefined) { - printf( - "at gdd lib limit => read of PV attribute \"%s\" will fail\n", pName); - return S_gddAppFuncTable_gddLimit; - } -# ifdef DEBUG - printf("installing PV attribute %s = %d\n", pName, type); -# endif - return this->installReadFunc(type, pMFuncIn); - } + gddAppReadFunc pMFuncIn); // // @@ -142,119 +137,5 @@ private: void newTbl(unsigned neMaxType); }; - -// -// gddAppFuncTable::newTbl() -// -// The total number of application tags to manage should be -// hidden from the application -// -template -inline void gddAppFuncTable::newTbl(unsigned newApplTypeMax) -{ - gddAppReadFunc *pMNewFuncTbl; - unsigned maxApp; - unsigned i; - - if (this->appTableNElem>newApplTypeMax) { - return; - } - maxApp = newApplTypeMax+(1u<<6u); -#ifdef _MSC_VER -// -// Right now all MS Visual C++ compilers allocate the -// wrong amount of memory (i.e. too little) -// for member function pointers, -// only explicit calculation via sizeof() works. -// For future versions this may become "if _MSC_VER < ???"... -// - pMNewFuncTbl = (gddAppReadFunc *) - new char[sizeof(gddAppReadFunc) * maxApp]; -#else - pMNewFuncTbl = new gddAppReadFunc[maxApp]; -#endif - if (pMNewFuncTbl) { - for (i=0u; iappTableNElem) { - pMNewFuncTbl[i] = this->pMFuncRead[i]; - } - else { - // - // some versions of NULL include (void *) cast - // (so I am using vanilla zero here) - // - pMNewFuncTbl[i] = 0; - } - } - if (this->pMFuncRead) { - delete [] this->pMFuncRead; - } - this->pMFuncRead = pMNewFuncTbl; - this->appTableNElem = maxApp; - } -} - - -// -// gddAppFuncTable::read() -// -// (g++ generates "multiply defined symbols" message unless I set this -// to be inline) -// -template -inline gddAppFuncTableStatus gddAppFuncTable::read(PV &pv, gdd &value) -{ - gddAppFuncTableStatus status; - - // - // if this gdd is a container then step through it - // and fetch all of the values inside - // - if (value.isContainer()) { - gddContainer *pCont = (gddContainer *) &value; - gddCursor curs = pCont->getCursor(); - gdd *pItem; - - status = S_gddAppFuncTable_Success; - for (pItem=curs.first(); pItem; pItem=curs.next()) - { - status = this->read(pv, *pItem); - if (status) { - break; - } - } - return status; - } - return callReadFunc(pv, value); -} - -// -// gddAppFuncTable::callReadFunc() -// -template -inline gddAppFuncTableStatus gddAppFuncTable::callReadFunc (PV &pv, gdd &value) -{ - unsigned type = value.applicationType(); - gddAppReadFunc pFunc; - - // - // otherwise call the function associated - // with this application type - // - type = value.applicationType(); - if (type>=this->appTableNElem) { - errPrintf (S_gddAppFuncTable_badType, __FILE__, - __LINE__, "- large appl type code = %u\n", - type); - return S_gddAppFuncTable_badType; - } - pFunc = this->pMFuncRead[type]; - if (pFunc==NULL) { - errPrintf (S_gddAppFuncTable_badType, __FILE__, - __LINE__, "- ukn appl type code = %u\n", - type); - return S_gddAppFuncTable_badType; - } - return (pv.*pFunc)(value); -} +#endif // gddAppFuncTableH