diff --git a/src/libCom/errMtst.c b/src/libCom/errMtst.c index cb71b899a..8e8c709ff 100644 --- a/src/libCom/errMtst.c +++ b/src/libCom/errMtst.c @@ -1,8 +1,7 @@ -/* errMtst.c */ -/* share/src/libCom @(#)errSymFind.c 1.3 2/4/92 */ -/* +/* share/src/libCom $Id$ + * errMtst.c * Author: Bob Zieman - * Date: 6-1-91 + * Date: 09-01-93 * * Experimental Physics and Industrial Control System (EPICS) * @@ -29,105 +28,59 @@ * ----------------- * .01 mm-dd-yy iii Comment */ -/* errSymFind.c - Locate error symbol */ - -#include #ifdef vxWorks #include -#include -#include -extern caddr_t statSymTbl; #else #include -extern int sys_nerr; -extern char *sys_errlist[]; #endif +#include +#include -int -errSymFind(status, name) - long status; - char *name; -{ - long value; -#ifdef vxWorks - unsigned char type; -#endif - unsigned short modnum; - modnum = (status >> 16); - if (modnum <= 500) -#ifdef vxWorks - symFindByValue((SYMTAB_ID)statSymTbl, status, name,(int*) &value, (SYM_TYPE*)&type); -#else - UnixSymFind(status, name, &value); -#endif - else - ModSymFind(status, name, &value); - if (value != status) - return (-1); - else - return (0); -} - + +/**************************************************************** + * MAIN FOR errMtst +****************************************************************/ #ifndef vxWorks -int -UnixSymFind(status, pname, pvalue) - long status; - char *pname; - long *pvalue; +main() { - if (status >= sys_nerr || status < 1) { - *pvalue = -1; - return; - } - strcpy(pname, sys_errlist[status]); - *pvalue = status; - return; + printf("calling errSymBld from main in errMtst.c\n"); + errSymBld(); +#if 0 + printf("calling errSymDump from main in errMtst.c\n"); + errSymDump(); + printf("calling errSymFindTst from main in errMtst.c\n"); + errSymFindTst(); +#endif + printf("calling errSymTest from main in errMtst.c\n"); + errSymTest((unsigned short)501, 0, 17); } #endif - -int -ModSymFind(status, pname, pvalue) - long status; - char *pname; - long *pvalue; + +/**************************************************************** + * ERRSYMTEST +****************************************************************/ +/* errSymTest: test error numbers */ +#ifdef __STDC__ +void errSymTest(unsigned short modnum, unsigned short begErrNum, unsigned short endErrNum) +#else +void errSymTest(modnum, begErrNum, endErrNum) +unsigned short modnum; +unsigned short begErrNum; +unsigned short endErrNum; +#endif /* __STDC__ */ { - unsigned short modNum; - unsigned short modDim; - unsigned short errOff; - unsigned short errDim; - /* lsb status must be odd */ - if (!(status & 0x1)) { - *pvalue = -1; + long errNum; + unsigned short errnum; + if (modnum < 501) return; + + /* get and print the range */ + for (errnum = begErrNum; errnum < endErrNum; errnum++) { + errNum = modnum << 16; + errNum |= (errnum & 0xffff); + printf("DEBUG errSymTest: errNum=%ld\n", errNum); +/* errSymTestPrint(errNum);*/ } - modNum = (status >> 16); - if (modNum < 501) { - *pvalue = -1; - return; - } - modNum = modNum - 501; - if (!dbErrDes->papErrSet[modNum]) { - *pvalue = -1; - return; - } - modDim = dbErrDes->number; - if (modNum >= modDim) { - *pvalue = -1; - return; - } - errDim = dbErrDes->papErrSet[modNum]->number; - errOff = (status & 0xffff) >> 1; - if (errOff >= errDim) { - *pvalue = -1; - return; - } - if (!dbErrDes->papErrSet[modNum]->papName[errOff]) { - *pvalue = -1; - return; - } - strcpy(pname, dbErrDes->papErrSet[modNum]->papName[errOff]); - *pvalue = status; - return; } diff --git a/src/libCom/errSymLib.c b/src/libCom/errSymLib.c index 63670e107..d4730b97f 100644 --- a/src/libCom/errSymLib.c +++ b/src/libCom/errSymLib.c @@ -1,6 +1,5 @@ -====================INCLUDES=============================== -=================================================== -/* +/* share/src/libCom $Id$ + * errSymLib.c * Author: Marty Kraimer * Date: 6-1-90 * @@ -25,86 +24,11 @@ * Advanced Photon Source * Argonne National Laboratory * - * Modification Log: + * Modification Log: errSymLib.c * ----------------- - * .01 mm-dd-yy iii Comment - */ - - - -/* - * - * 1. Put everything in errSymLib.c - * get rid of error.h - * function prototypes in errMdef.h - * 2. Nick to fix calink.h error comments. - * 3. Fix trailing blanks on S_... - * 4. In iocinit - make a call to errSymFind to make it initialize. - * - * - * - * - * - * - * - * - * - * - * - */ - - -typedef struct errNumNode { - ELLNODE node; - struct errNumNode *hashnode; - long errNum; -} ERRNUMNODE; - -#define NHASH 256 - -static ELLLIST errNumList; - -static ERRNUMNODE *hashtable[NHASH]; - -/* - * when building keep in sorted order - */ - -hash = (NHASH - (modnum-500) + errNum) % NHASH; - - - -static int initialized = FALSE; - -#if 0 /* from error.h */ -#define LOCAL static -#define NELEMENTS(array) /* number of elements in an array */ \ - (sizeof (array) / sizeof ((array) [0])) - -typedef struct /* ERRSYMBOL - entry in symbol table */ - { - char *name; /* pointer to symbol name */ - long errNum; /* errMessage symbol number */ - } ERRSYMBOL; -typedef struct /* ERRSYMTAB - symbol table */ - { - short nsymbols; /* current number of symbols in table */ - ERRSYMBOL *symbols; /* ptr to array of symbol entries */ - } ERRSYMTAB; -typedef ERRSYMTAB *ERRSYMTAB_ID; - -#ifdef vxWorks -#define MYERRNO (errnoGet()&0xffff) -#else -#define MYERRNO errno -#endif - -#endif /* from error.h */ - - -/*********************************************************************/ -/* @(#)errMessage.c 1.8 8/11/93 */ -/* Modification Log: + * .01 mm-dd-yy rcz See below for Creation/Merge + **** Merged Modification Logs: + * Modification Log: errMessage.c * ----------------- * .01 10-08-91 mrk Allow logMsg or printF * .02 03-10-93 joh expanded errMessage() to accept the @@ -115,51 +39,128 @@ typedef ERRSYMTAB *ERRSYMTAB_ID; * created macro errMessage() that calls * errPrintf with __FILE__ and __LINE__ * as arguments - */ - -/* errMessage.c - Handle error messages */ - -/*************************************************************************** + * errMessage.c - Handle error messages + *************************************************************************** * This must ultimately be replaced by a facility that allows remote * nodes access to the error messages. A message handling communication * task should be written that allows multiple remote nodes to request * notification of all error messages. * For now lets just print messages and last errno via logMsg or printf - ***************************************************************************/ + *************************************************************************** + * Modification Log: errPrint.c + * ----------------- + * .01 10-08-91 mrk Allow logMsg or printf + * .02 04-29-93 joh extra arg for errPrint() + * .03 04-29-93 joh errPrint() became errPrintStatus() + * .04 05-06-93 joh errPrintStatus() get var args + * for vprintf() + * Modification Log: errSymLib.c + * ----------------- + * .01 09-04-93 rcz Merged errMessage.c, errPrint.c, errSymFind.c + * rcz into one file (errSymLib.c) and changed method + * rcz of errSymTable lookup. + */ + +/* + * TODO + * 1. Put everything in errSymLib.c - DONE + * get rid of error.h - DONE + * function prototypes in errMdef.h - (DONE ???) + * 2. Nick to fix calink.h error comments. + * 3. Fix trailing blanks on S_... -- DONE + * 4. In iocinit - make a call to errSymBld to make it initialize. + * + */ + +/****************************** + * FUNCTIONS + * errhash - NEW + * errPrintf - N/C + * errPrintStatus - N/C + * verrPrintStatus - N/C + * errSymBld - complete rework + * errSymbolAdd - NEW + * errSymbolFind - NEW + * errSymFind + * UnixSymFind - N/C + * ModSymFind + * errSymDump - NEW + * errSymFindTst - NEW + * main - in errMtst.c + * Program errMtst calls: + * errSymBld + * errSymDump + * errSymFindTst + * + * errSymTest - in errMtst.c - not implemented yet (not needed ??? ) + * errSymTest(501, 0, 100) + * errSymTest(int modnum, int begErrNum, int endErrNum) + ***********************************/ + +#include +#include +#include +#include #ifdef vxWorks #include -/*#include */ -/*#include */ -/*#include */ #include +#include #include +#include + +extern SYMTAB_ID statSymTbl; + +extern int errToLogMsg; #else -#include #include #include #include +extern int errno; +extern int sys_nerr; +extern char *sys_errlist[]; #endif -#include -#include -#include + +static ELLLIST errnumlist; +static ERRNUMNODE hashtable[NHASH]; +static int initialized = FALSE; extern ERRSYMTAB_ID errSymTbl; -#if 0 -extern char *calloc(); -#endif -struct errDes *dbErrDes = NULL; + + #ifdef vxWorks int errToLogMsg = FALSE; #endif /*Declare storage for errVerbose( defined in errMdef.h)*/ - int errVerbose=0; -/* - * ERRMESSAGE - */ + +/**************************************************************** + * HASH + * returns the hash index of errNum +****************************************************************/ +#ifdef __STDC__ +static +unsigned short errhash(long errNum) +#else +static +unsigned short errhash(errNum) +long errNum; +#endif /* __STDC__ */ +{ +unsigned short modnum; +unsigned short errnum; + + modnum = errNum >> 16; + errnum = errNum & 0xffff; + return((((modnum - 500) * 10) + errnum) % NHASH); +} + +/**************************************************************** + * ERRMESSAGE - now a macro to call errPrintf + * ERRPRINTF - print an error symbol message + ***************************************************************/ #ifdef __STDC__ void errPrintf(long status, char *pFileName, int lineno, char *pformat, ...) #else @@ -193,10 +194,6 @@ va_dcl pformat = va_arg(pvar, char *); #endif - if (!dbErrDes) - if (errSymBld()) - exit(1); - #ifdef vxWorks if(!errToLogMsg) { id = taskIdSelf(); @@ -240,12 +237,12 @@ va_dcl reformatSize = size; } else{ -# ifdef vxWorks - logMsg("%s: calloc error\n", __FILE__); -# else - printf("%s: calloc error\n", __FILE__); -# endif - return; +#ifdef vxWorks + logMsg("%s: calloc error\n", __FILE__); +#else + printf("%s: calloc error\n", __FILE__); +#endif + return; } } strcpy(pReformat, pformat); @@ -257,198 +254,70 @@ va_dcl return; } - -/* + +/**************************************************************** * ERRSYMBLD * - * Create and initializes the dbErrDes structure. - * This allows direct lookup of Module error messages. + * Create the normal ell LIST of sorted error messages nodes + * Followed by linked hash lists - that thread together those + * ell nodes that have a common hash number. * - */ - -errSymBld() + * The hash will get you to the top of a singly linked hash list + * A linear search is then performed to find the place to + * plant/retrieve the next hashed link/message. + ***************************************************************/ +int errSymBld() { - struct errDes *pTdbErrDes; ERRSYMBOL *errArray = errSymTbl->symbols; ERRSYMBOL *perrArray; - + ELLLIST *perrnumlist = &errnumlist; + ERRNUMNODE *perrNumNode = NULL; + ERRNUMNODE *pNextNode = NULL; + ERRNUMNODE *pLastNode = NULL; + ERRNUMNODE *phashtable = hashtable; int i; - int j; int modnum; - int modoff; - int errnum; - int erroff; - int entDim; - int modDim = 0; - long Size = 0; - char *addrI; - perrArray = errArray; + unsigned short hashInd; - /* determine the maximum module number */ for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) { modnum = errArray->errNum >> 16; - modoff = modnum - 501; - errnum = errArray->errNum & 0xffff; - erroff = errnum >> 1; if (modnum < 501) { printf("errSymBld: ERROR - Module number in errSymTbl < 501\n"); return (-1); } - modDim = modDim <= modoff ? modoff + 1 : modDim; - } - /* allocate pTdbErrDes structure */ - if ((pTdbErrDes = (struct errDes *) - calloc(1, (unsigned) sizeof(struct errDes))) == NULL) { - printf("errSymBld: calloc error\n"); - return (-1); - } - Size = sizeof(struct errDes); - - /* allocate papErrSet pointer array */ - if ((pTdbErrDes->papErrSet = (struct errSet **) - calloc(1, (unsigned) modDim * sizeof(caddr_t))) == NULL) { - printf("errSymBld: calloc error\n"); - return (-1); - } - pTdbErrDes->number = modDim; - Size += pTdbErrDes->number * sizeof(caddr_t); - - /* allocate a temp structure for each module */ - /* and insert the maximum dimension for it's messages */ - errArray = perrArray ; - for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) { - modnum = errArray->errNum >> 16; - modoff = modnum - 501; - errnum = errArray->errNum & 0xffff; - erroff = errnum >> 1; - /* has module been allocated yet */ - if (!pTdbErrDes->papErrSet[modoff]) { - /* assign a structure for each module */ - if ((pTdbErrDes->papErrSet[modoff] = (struct errSet *) - calloc(1, (unsigned) sizeof(struct errSet))) == NULL) { - printf("errSymBld: calloc error\n"); - return (-1); - } - Size += sizeof(struct errSet); - } - /* determine max message number in each module */ - /* max entries in each module */ - entDim = pTdbErrDes->papErrSet[modoff]->number; - entDim = entDim <= erroff ? erroff + 1 : entDim; - pTdbErrDes->papErrSet[modoff]->number = entDim; - } - /* allocate a temp pointer array for each module */ - /* and insert pointer to err string */ - - errArray = perrArray ; - for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) { - modnum = errArray->errNum >> 16; - modoff = modnum - 501; - errnum = errArray->errNum & 0xffff; - erroff = errnum >> 1; - if (pTdbErrDes->papErrSet[modoff]) { - if (!pTdbErrDes->papErrSet[modoff]->papName) { - /* allocate ptr array */ - if (!pTdbErrDes->papErrSet[modoff]->papName) { - if ((pTdbErrDes->papErrSet[modoff]->papName = (caddr_t *) - calloc(1, (unsigned) pTdbErrDes->papErrSet[modoff]->number - * sizeof(caddr_t))) == NULL) { - printf("errSymBld: calloc error\n"); - return (-1); - } - Size += pTdbErrDes->papErrSet[modoff]->number * sizeof(caddr_t); - } - } - if (!pTdbErrDes->papErrSet[modoff]->papName[erroff]) { - pTdbErrDes->papErrSet[modoff]->papName[erroff] = errArray->name; - } + if ((errSymbolAdd(errArray->errNum, errArray->name)) <0 ) { + printf("errSymBld: ERROR - errSymbolAdd() failed \n"); + return (-1); } } + perrNumNode = (ERRNUMNODE *) ellFirst(perrnumlist); + while (perrNumNode) { + /* hash each perrNumNode->errNum */ + hashInd = errhash(perrNumNode->errNum); - /* allocate the contiguous area */ - if ((dbErrDes = (struct errDes *) calloc(1, (unsigned) Size)) == NULL) { - printf("errSymBld: calloc error\n"); - return (-1); - } - addrI = (caddr_t) dbErrDes + sizeof(struct errDes); - dbErrDes->papErrSet = (struct errSet **) addrI; - dbErrDes->number = pTdbErrDes->number; - addrI += dbErrDes->number * sizeof(caddr_t); - - /* insert number nd pointers and strings */ - for (i = 0; i < dbErrDes->number; i++) { - if (pTdbErrDes->papErrSet[i]) { - dbErrDes->papErrSet[i] = (struct errSet *) addrI; - addrI += sizeof(struct errSet); - dbErrDes->papErrSet[i]->number = pTdbErrDes->papErrSet[i]->number; - dbErrDes->papErrSet[i]->papName = (caddr_t *) addrI; - addrI += dbErrDes->papErrSet[i]->number * sizeof(caddr_t); - for (j = 0; j < dbErrDes->papErrSet[i]->number; j++) { - if (pTdbErrDes->papErrSet[i]->papName[j]) { - dbErrDes->papErrSet[i]->papName[j] - = pTdbErrDes->papErrSet[i]->papName[j]; - } - } + /* if the hash table entry is empty - fill it */ + if ( phashtable[hashInd].hashnode == NULL ) { + phashtable[hashInd].hashnode = perrNumNode; + perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode); + continue; /* and go to next entry */ } + /* else search for the end of this hashed link list */ + pNextNode = phashtable[hashInd].hashnode; + /* search for last node (NULL) of hashnode linked list */ + while (pNextNode) { + pLastNode = pNextNode; + pNextNode = pNextNode->hashnode; + } + pLastNode->hashnode = perrNumNode; + perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode); } -return(0); -} /* end of errMessage.c */ -/*********************************************************************/ -/* errPrint.c */ -/* @(#)errPrint.c 1.6 8/13/93*/ -/* - * Author: Bob Zieman - * Date: 6-1-91 - * - * 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 - * - * Modification Log: - * ----------------- - * .01 10-08-91 mrk Allow logMsg or printf - * .02 04-29-93 joh extra arg for errPrint() - * .03 04-29-93 joh errPrint() became errPrintStatus() - * .04 05-06-93 joh errPrintStatus() get var args - * for vprintf() - */ - -/* errPrint.c - print error symbol */ -#ifdef vxWorks - extern int errToLogMsg; -# include -# include -# include -# include -#else - extern int errno; -#endif vxWorks - -#include -#include -#include - + initialized = TRUE; + return(0); +} -/* - * errPrintStatus() - */ +/**************************************************************** + * ERRPRINTSTATUS + ***************************************************************/ #ifdef __STDC__ int errPrintStatus(long status, char *pFormat, ...) #else @@ -472,11 +341,10 @@ va_dcl return verrPrintStatus(status, pFormat, pvar); } - -/* - * verrPrintStatus - */ +/**************************************************************** + * VERRPRINTSTATUS + ***************************************************************/ #ifdef __STDC__ int verrPrintStatus(long status, char *pFormatString, va_list pvar) #else @@ -557,6 +425,235 @@ va_list pvar; return rtnval; } -/*********************************************************************/ -errSymFind.c -/*********************************************************************/ + +/**************************************************************** + * ERRSYMBOLFIND + ***************************************************************/ +#ifdef __STDC__ +static ERRNUMNODE *errSymbolFind (long errNum) +#else +static ERRNUMNODE *errSymbolFind(errNum) +long errNum; +#endif /* __STDC__ */ +{ + unsigned short hashInd; + ERRNUMNODE *pNextNode = NULL; + ERRNUMNODE *phashtable = hashtable; + + hashInd = errhash(errNum); + if ((pNextNode = phashtable[hashInd].hashnode) == NULL) { + return (NULL); + } + pNextNode = phashtable[hashInd].hashnode; + /* search for match of errNum */ + while (pNextNode) { + if (pNextNode->errNum == errNum) + return(pNextNode); + pNextNode = pNextNode->hashnode; + } + return (NULL); +} + +/**************************************************************** + * ERRSYMBOLADD + * adds symbols to the master errnumlist in sorted errNum order + ***************************************************************/ +#ifdef __STDC__ +int errSymbolAdd (long errNum,char *name) +#else +int errSymbolAdd (errNum,name) +long errNum; +char *name; +#endif /* __STDC__ */ +{ + ELLLIST *perrnumlist = &errnumlist; + ERRNUMNODE *pNew; + ERRNUMNODE *perrNumNode; + ERRNUMNODE *prevNumNode; + int insert; + int len; + + pNew = (ERRNUMNODE*)dbCalloc(1, sizeof(ERRNUMNODE)); + pNew->errNum = errNum; + len = strlen(name); + pNew->message = (char *)dbCalloc(1, len+1); + memcpy(pNew->message, name, len); + /* find the place to put the new node */ + perrNumNode = (ERRNUMNODE *) ellFirst(perrnumlist); + insert = 0; + while (perrNumNode) { + if (perrNumNode->errNum >= errNum) { /* too far */ + insert = 1; + break; + } + perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode); + } + if (insert) { + prevNumNode = (ERRNUMNODE*)ellPrevious(perrNumNode); + ellInsert(perrnumlist,(ELLNODE*)prevNumNode,(ELLNODE*)pNew); + } else { + ellAdd(perrnumlist,(ELLNODE*)pNew); + } + return(0); +} + +/**************************************************************** + * UNIXSYMFIND + ***************************************************************/ +#ifndef vxWorks +#ifdef __STDC__ +int UnixSymFind(long status, char *pname, long *pvalue); +#else +int UnixSymFind(status, pname, pvalue) + long status; + char *pname; + long *pvalue; +#endif /* __STDC__ */ +{ + if (status >= sys_nerr || status < 1) { + *pvalue = -1; + return; + } + strcpy(pname, sys_errlist[status]); + *pvalue = status; + return; +} +#endif + +/**************************************************************** + * MODSYMFIND + ***************************************************************/ +#ifdef __STDC__ +int ModSymFind(long status, char *pname, long *pvalue) +#else +int ModSymFind(status, pname, pvalue) + long status; + char *pname; + long *pvalue; +#endif /* __STDC__ */ +{ + unsigned short modNum; + ERRNUMNODE *pRetNode; + + modNum = (status >> 16); + if (modNum < 501) { + *pvalue = -1; + return; + } + if ((pRetNode = errSymbolFind(status)) == NULL) { + *pvalue = -1; + return; + } + strcpy(pname, pRetNode->message); + *pvalue = status; + return; +} + +/**************************************************************** + * ERRSYMFIND + ***************************************************************/ +#ifdef __STDC__ +int errSymFind(long status, char *name) +#else +/* errSymFind - Locate error symbol */ +int errSymFind(status, name) + long status; + char *name; +#endif /* __STDC__ */ +{ + long value; +#ifdef vxWorks + unsigned char type; +#endif + unsigned short modnum; + + if (!initialized) { + printf("\nerrSymFind: Aborting because errSymBld didn't initialize\n"); + return (-1); + } + + modnum = (status >> 16); + if (modnum <= 500) +#ifdef vxWorks + symFindByValue((SYMTAB_ID)statSymTbl, status, name,(int*) &value, (SYM_TYPE*)&type); +#else + UnixSymFind(status, name, &value); +#endif + else + ModSymFind(status, name, &value); + if (value != status) + return (-1); + else + return (0); +} + +/**************************************************************** + * ERRSYMFINDTST + ***************************************************************/ +void errSymFindTst() +{ + ERRNUMNODE *phashtable = hashtable; + ERRNUMNODE *pNextNode; + char message[128]; + unsigned short modnum; + unsigned short errnum; + int i; + + for ( i=0; ierrNum >> 16); + errnum = pNextNode->errNum & 0xffff; + if((errSymFind (pNextNode->errNum, message)) <0 ) + { + printf("errSymFindTst: errSymFind FAILED - modnum=%d errnum=%d\n" + ,modnum ,errnum); + } + printf("hash_no=%d mod=%d num=%d errmess=\"%s\"\n" + , i, modnum, errnum, message); + pNextNode = pNextNode->hashnode; + } + } +return; +} + +/**************************************************************** + * errSymDump + ***************************************************************/ +#ifdef __STDC__ +void errSymDump() +#else +void errSymDump() +#endif /* __STDC__ */ +{ +ERRNUMNODE *phashtable; +ERRNUMNODE *pNextNode; +ERRNUMNODE *pLastNode; +int i; +int modnum; +int errnum; +int msgcount; + + phashtable = hashtable; + msgcount = 0; + printf("\nerrSymDump: HASH NUMBER=%d\n", NHASH); + for ( i=0; i < NHASH; i++) { + if ( (pNextNode = phashtable[i].hashnode) == NULL ) + continue; + printf("\nHASHNODE=%d\n", i); + while (pNextNode) { + modnum = pNextNode->errNum >> 16; + errnum = pNextNode->errNum & 0xffff; + printf("\tmodule=%d errnum=%d\n\tmessage=\"%s\"\n" + , modnum , errnum , pNextNode->message); + msgcount++; + pLastNode = pNextNode; + pNextNode=pNextNode->hashnode; + } + } + printf("\nerrSymDump: total number of error messages=%d\n", msgcount); +} diff --git a/src/libCom/error/errSymLib.c b/src/libCom/error/errSymLib.c index 63670e107..d4730b97f 100644 --- a/src/libCom/error/errSymLib.c +++ b/src/libCom/error/errSymLib.c @@ -1,6 +1,5 @@ -====================INCLUDES=============================== -=================================================== -/* +/* share/src/libCom $Id$ + * errSymLib.c * Author: Marty Kraimer * Date: 6-1-90 * @@ -25,86 +24,11 @@ * Advanced Photon Source * Argonne National Laboratory * - * Modification Log: + * Modification Log: errSymLib.c * ----------------- - * .01 mm-dd-yy iii Comment - */ - - - -/* - * - * 1. Put everything in errSymLib.c - * get rid of error.h - * function prototypes in errMdef.h - * 2. Nick to fix calink.h error comments. - * 3. Fix trailing blanks on S_... - * 4. In iocinit - make a call to errSymFind to make it initialize. - * - * - * - * - * - * - * - * - * - * - * - */ - - -typedef struct errNumNode { - ELLNODE node; - struct errNumNode *hashnode; - long errNum; -} ERRNUMNODE; - -#define NHASH 256 - -static ELLLIST errNumList; - -static ERRNUMNODE *hashtable[NHASH]; - -/* - * when building keep in sorted order - */ - -hash = (NHASH - (modnum-500) + errNum) % NHASH; - - - -static int initialized = FALSE; - -#if 0 /* from error.h */ -#define LOCAL static -#define NELEMENTS(array) /* number of elements in an array */ \ - (sizeof (array) / sizeof ((array) [0])) - -typedef struct /* ERRSYMBOL - entry in symbol table */ - { - char *name; /* pointer to symbol name */ - long errNum; /* errMessage symbol number */ - } ERRSYMBOL; -typedef struct /* ERRSYMTAB - symbol table */ - { - short nsymbols; /* current number of symbols in table */ - ERRSYMBOL *symbols; /* ptr to array of symbol entries */ - } ERRSYMTAB; -typedef ERRSYMTAB *ERRSYMTAB_ID; - -#ifdef vxWorks -#define MYERRNO (errnoGet()&0xffff) -#else -#define MYERRNO errno -#endif - -#endif /* from error.h */ - - -/*********************************************************************/ -/* @(#)errMessage.c 1.8 8/11/93 */ -/* Modification Log: + * .01 mm-dd-yy rcz See below for Creation/Merge + **** Merged Modification Logs: + * Modification Log: errMessage.c * ----------------- * .01 10-08-91 mrk Allow logMsg or printF * .02 03-10-93 joh expanded errMessage() to accept the @@ -115,51 +39,128 @@ typedef ERRSYMTAB *ERRSYMTAB_ID; * created macro errMessage() that calls * errPrintf with __FILE__ and __LINE__ * as arguments - */ - -/* errMessage.c - Handle error messages */ - -/*************************************************************************** + * errMessage.c - Handle error messages + *************************************************************************** * This must ultimately be replaced by a facility that allows remote * nodes access to the error messages. A message handling communication * task should be written that allows multiple remote nodes to request * notification of all error messages. * For now lets just print messages and last errno via logMsg or printf - ***************************************************************************/ + *************************************************************************** + * Modification Log: errPrint.c + * ----------------- + * .01 10-08-91 mrk Allow logMsg or printf + * .02 04-29-93 joh extra arg for errPrint() + * .03 04-29-93 joh errPrint() became errPrintStatus() + * .04 05-06-93 joh errPrintStatus() get var args + * for vprintf() + * Modification Log: errSymLib.c + * ----------------- + * .01 09-04-93 rcz Merged errMessage.c, errPrint.c, errSymFind.c + * rcz into one file (errSymLib.c) and changed method + * rcz of errSymTable lookup. + */ + +/* + * TODO + * 1. Put everything in errSymLib.c - DONE + * get rid of error.h - DONE + * function prototypes in errMdef.h - (DONE ???) + * 2. Nick to fix calink.h error comments. + * 3. Fix trailing blanks on S_... -- DONE + * 4. In iocinit - make a call to errSymBld to make it initialize. + * + */ + +/****************************** + * FUNCTIONS + * errhash - NEW + * errPrintf - N/C + * errPrintStatus - N/C + * verrPrintStatus - N/C + * errSymBld - complete rework + * errSymbolAdd - NEW + * errSymbolFind - NEW + * errSymFind + * UnixSymFind - N/C + * ModSymFind + * errSymDump - NEW + * errSymFindTst - NEW + * main - in errMtst.c + * Program errMtst calls: + * errSymBld + * errSymDump + * errSymFindTst + * + * errSymTest - in errMtst.c - not implemented yet (not needed ??? ) + * errSymTest(501, 0, 100) + * errSymTest(int modnum, int begErrNum, int endErrNum) + ***********************************/ + +#include +#include +#include +#include #ifdef vxWorks #include -/*#include */ -/*#include */ -/*#include */ #include +#include #include +#include + +extern SYMTAB_ID statSymTbl; + +extern int errToLogMsg; #else -#include #include #include #include +extern int errno; +extern int sys_nerr; +extern char *sys_errlist[]; #endif -#include -#include -#include + +static ELLLIST errnumlist; +static ERRNUMNODE hashtable[NHASH]; +static int initialized = FALSE; extern ERRSYMTAB_ID errSymTbl; -#if 0 -extern char *calloc(); -#endif -struct errDes *dbErrDes = NULL; + + #ifdef vxWorks int errToLogMsg = FALSE; #endif /*Declare storage for errVerbose( defined in errMdef.h)*/ - int errVerbose=0; -/* - * ERRMESSAGE - */ + +/**************************************************************** + * HASH + * returns the hash index of errNum +****************************************************************/ +#ifdef __STDC__ +static +unsigned short errhash(long errNum) +#else +static +unsigned short errhash(errNum) +long errNum; +#endif /* __STDC__ */ +{ +unsigned short modnum; +unsigned short errnum; + + modnum = errNum >> 16; + errnum = errNum & 0xffff; + return((((modnum - 500) * 10) + errnum) % NHASH); +} + +/**************************************************************** + * ERRMESSAGE - now a macro to call errPrintf + * ERRPRINTF - print an error symbol message + ***************************************************************/ #ifdef __STDC__ void errPrintf(long status, char *pFileName, int lineno, char *pformat, ...) #else @@ -193,10 +194,6 @@ va_dcl pformat = va_arg(pvar, char *); #endif - if (!dbErrDes) - if (errSymBld()) - exit(1); - #ifdef vxWorks if(!errToLogMsg) { id = taskIdSelf(); @@ -240,12 +237,12 @@ va_dcl reformatSize = size; } else{ -# ifdef vxWorks - logMsg("%s: calloc error\n", __FILE__); -# else - printf("%s: calloc error\n", __FILE__); -# endif - return; +#ifdef vxWorks + logMsg("%s: calloc error\n", __FILE__); +#else + printf("%s: calloc error\n", __FILE__); +#endif + return; } } strcpy(pReformat, pformat); @@ -257,198 +254,70 @@ va_dcl return; } - -/* + +/**************************************************************** * ERRSYMBLD * - * Create and initializes the dbErrDes structure. - * This allows direct lookup of Module error messages. + * Create the normal ell LIST of sorted error messages nodes + * Followed by linked hash lists - that thread together those + * ell nodes that have a common hash number. * - */ - -errSymBld() + * The hash will get you to the top of a singly linked hash list + * A linear search is then performed to find the place to + * plant/retrieve the next hashed link/message. + ***************************************************************/ +int errSymBld() { - struct errDes *pTdbErrDes; ERRSYMBOL *errArray = errSymTbl->symbols; ERRSYMBOL *perrArray; - + ELLLIST *perrnumlist = &errnumlist; + ERRNUMNODE *perrNumNode = NULL; + ERRNUMNODE *pNextNode = NULL; + ERRNUMNODE *pLastNode = NULL; + ERRNUMNODE *phashtable = hashtable; int i; - int j; int modnum; - int modoff; - int errnum; - int erroff; - int entDim; - int modDim = 0; - long Size = 0; - char *addrI; - perrArray = errArray; + unsigned short hashInd; - /* determine the maximum module number */ for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) { modnum = errArray->errNum >> 16; - modoff = modnum - 501; - errnum = errArray->errNum & 0xffff; - erroff = errnum >> 1; if (modnum < 501) { printf("errSymBld: ERROR - Module number in errSymTbl < 501\n"); return (-1); } - modDim = modDim <= modoff ? modoff + 1 : modDim; - } - /* allocate pTdbErrDes structure */ - if ((pTdbErrDes = (struct errDes *) - calloc(1, (unsigned) sizeof(struct errDes))) == NULL) { - printf("errSymBld: calloc error\n"); - return (-1); - } - Size = sizeof(struct errDes); - - /* allocate papErrSet pointer array */ - if ((pTdbErrDes->papErrSet = (struct errSet **) - calloc(1, (unsigned) modDim * sizeof(caddr_t))) == NULL) { - printf("errSymBld: calloc error\n"); - return (-1); - } - pTdbErrDes->number = modDim; - Size += pTdbErrDes->number * sizeof(caddr_t); - - /* allocate a temp structure for each module */ - /* and insert the maximum dimension for it's messages */ - errArray = perrArray ; - for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) { - modnum = errArray->errNum >> 16; - modoff = modnum - 501; - errnum = errArray->errNum & 0xffff; - erroff = errnum >> 1; - /* has module been allocated yet */ - if (!pTdbErrDes->papErrSet[modoff]) { - /* assign a structure for each module */ - if ((pTdbErrDes->papErrSet[modoff] = (struct errSet *) - calloc(1, (unsigned) sizeof(struct errSet))) == NULL) { - printf("errSymBld: calloc error\n"); - return (-1); - } - Size += sizeof(struct errSet); - } - /* determine max message number in each module */ - /* max entries in each module */ - entDim = pTdbErrDes->papErrSet[modoff]->number; - entDim = entDim <= erroff ? erroff + 1 : entDim; - pTdbErrDes->papErrSet[modoff]->number = entDim; - } - /* allocate a temp pointer array for each module */ - /* and insert pointer to err string */ - - errArray = perrArray ; - for (i = 0; i < errSymTbl->nsymbols; i++, errArray++) { - modnum = errArray->errNum >> 16; - modoff = modnum - 501; - errnum = errArray->errNum & 0xffff; - erroff = errnum >> 1; - if (pTdbErrDes->papErrSet[modoff]) { - if (!pTdbErrDes->papErrSet[modoff]->papName) { - /* allocate ptr array */ - if (!pTdbErrDes->papErrSet[modoff]->papName) { - if ((pTdbErrDes->papErrSet[modoff]->papName = (caddr_t *) - calloc(1, (unsigned) pTdbErrDes->papErrSet[modoff]->number - * sizeof(caddr_t))) == NULL) { - printf("errSymBld: calloc error\n"); - return (-1); - } - Size += pTdbErrDes->papErrSet[modoff]->number * sizeof(caddr_t); - } - } - if (!pTdbErrDes->papErrSet[modoff]->papName[erroff]) { - pTdbErrDes->papErrSet[modoff]->papName[erroff] = errArray->name; - } + if ((errSymbolAdd(errArray->errNum, errArray->name)) <0 ) { + printf("errSymBld: ERROR - errSymbolAdd() failed \n"); + return (-1); } } + perrNumNode = (ERRNUMNODE *) ellFirst(perrnumlist); + while (perrNumNode) { + /* hash each perrNumNode->errNum */ + hashInd = errhash(perrNumNode->errNum); - /* allocate the contiguous area */ - if ((dbErrDes = (struct errDes *) calloc(1, (unsigned) Size)) == NULL) { - printf("errSymBld: calloc error\n"); - return (-1); - } - addrI = (caddr_t) dbErrDes + sizeof(struct errDes); - dbErrDes->papErrSet = (struct errSet **) addrI; - dbErrDes->number = pTdbErrDes->number; - addrI += dbErrDes->number * sizeof(caddr_t); - - /* insert number nd pointers and strings */ - for (i = 0; i < dbErrDes->number; i++) { - if (pTdbErrDes->papErrSet[i]) { - dbErrDes->papErrSet[i] = (struct errSet *) addrI; - addrI += sizeof(struct errSet); - dbErrDes->papErrSet[i]->number = pTdbErrDes->papErrSet[i]->number; - dbErrDes->papErrSet[i]->papName = (caddr_t *) addrI; - addrI += dbErrDes->papErrSet[i]->number * sizeof(caddr_t); - for (j = 0; j < dbErrDes->papErrSet[i]->number; j++) { - if (pTdbErrDes->papErrSet[i]->papName[j]) { - dbErrDes->papErrSet[i]->papName[j] - = pTdbErrDes->papErrSet[i]->papName[j]; - } - } + /* if the hash table entry is empty - fill it */ + if ( phashtable[hashInd].hashnode == NULL ) { + phashtable[hashInd].hashnode = perrNumNode; + perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode); + continue; /* and go to next entry */ } + /* else search for the end of this hashed link list */ + pNextNode = phashtable[hashInd].hashnode; + /* search for last node (NULL) of hashnode linked list */ + while (pNextNode) { + pLastNode = pNextNode; + pNextNode = pNextNode->hashnode; + } + pLastNode->hashnode = perrNumNode; + perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode); } -return(0); -} /* end of errMessage.c */ -/*********************************************************************/ -/* errPrint.c */ -/* @(#)errPrint.c 1.6 8/13/93*/ -/* - * Author: Bob Zieman - * Date: 6-1-91 - * - * 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 - * - * Modification Log: - * ----------------- - * .01 10-08-91 mrk Allow logMsg or printf - * .02 04-29-93 joh extra arg for errPrint() - * .03 04-29-93 joh errPrint() became errPrintStatus() - * .04 05-06-93 joh errPrintStatus() get var args - * for vprintf() - */ - -/* errPrint.c - print error symbol */ -#ifdef vxWorks - extern int errToLogMsg; -# include -# include -# include -# include -#else - extern int errno; -#endif vxWorks - -#include -#include -#include - + initialized = TRUE; + return(0); +} -/* - * errPrintStatus() - */ +/**************************************************************** + * ERRPRINTSTATUS + ***************************************************************/ #ifdef __STDC__ int errPrintStatus(long status, char *pFormat, ...) #else @@ -472,11 +341,10 @@ va_dcl return verrPrintStatus(status, pFormat, pvar); } - -/* - * verrPrintStatus - */ +/**************************************************************** + * VERRPRINTSTATUS + ***************************************************************/ #ifdef __STDC__ int verrPrintStatus(long status, char *pFormatString, va_list pvar) #else @@ -557,6 +425,235 @@ va_list pvar; return rtnval; } -/*********************************************************************/ -errSymFind.c -/*********************************************************************/ + +/**************************************************************** + * ERRSYMBOLFIND + ***************************************************************/ +#ifdef __STDC__ +static ERRNUMNODE *errSymbolFind (long errNum) +#else +static ERRNUMNODE *errSymbolFind(errNum) +long errNum; +#endif /* __STDC__ */ +{ + unsigned short hashInd; + ERRNUMNODE *pNextNode = NULL; + ERRNUMNODE *phashtable = hashtable; + + hashInd = errhash(errNum); + if ((pNextNode = phashtable[hashInd].hashnode) == NULL) { + return (NULL); + } + pNextNode = phashtable[hashInd].hashnode; + /* search for match of errNum */ + while (pNextNode) { + if (pNextNode->errNum == errNum) + return(pNextNode); + pNextNode = pNextNode->hashnode; + } + return (NULL); +} + +/**************************************************************** + * ERRSYMBOLADD + * adds symbols to the master errnumlist in sorted errNum order + ***************************************************************/ +#ifdef __STDC__ +int errSymbolAdd (long errNum,char *name) +#else +int errSymbolAdd (errNum,name) +long errNum; +char *name; +#endif /* __STDC__ */ +{ + ELLLIST *perrnumlist = &errnumlist; + ERRNUMNODE *pNew; + ERRNUMNODE *perrNumNode; + ERRNUMNODE *prevNumNode; + int insert; + int len; + + pNew = (ERRNUMNODE*)dbCalloc(1, sizeof(ERRNUMNODE)); + pNew->errNum = errNum; + len = strlen(name); + pNew->message = (char *)dbCalloc(1, len+1); + memcpy(pNew->message, name, len); + /* find the place to put the new node */ + perrNumNode = (ERRNUMNODE *) ellFirst(perrnumlist); + insert = 0; + while (perrNumNode) { + if (perrNumNode->errNum >= errNum) { /* too far */ + insert = 1; + break; + } + perrNumNode = (ERRNUMNODE *) ellNext((ELLNODE *) perrNumNode); + } + if (insert) { + prevNumNode = (ERRNUMNODE*)ellPrevious(perrNumNode); + ellInsert(perrnumlist,(ELLNODE*)prevNumNode,(ELLNODE*)pNew); + } else { + ellAdd(perrnumlist,(ELLNODE*)pNew); + } + return(0); +} + +/**************************************************************** + * UNIXSYMFIND + ***************************************************************/ +#ifndef vxWorks +#ifdef __STDC__ +int UnixSymFind(long status, char *pname, long *pvalue); +#else +int UnixSymFind(status, pname, pvalue) + long status; + char *pname; + long *pvalue; +#endif /* __STDC__ */ +{ + if (status >= sys_nerr || status < 1) { + *pvalue = -1; + return; + } + strcpy(pname, sys_errlist[status]); + *pvalue = status; + return; +} +#endif + +/**************************************************************** + * MODSYMFIND + ***************************************************************/ +#ifdef __STDC__ +int ModSymFind(long status, char *pname, long *pvalue) +#else +int ModSymFind(status, pname, pvalue) + long status; + char *pname; + long *pvalue; +#endif /* __STDC__ */ +{ + unsigned short modNum; + ERRNUMNODE *pRetNode; + + modNum = (status >> 16); + if (modNum < 501) { + *pvalue = -1; + return; + } + if ((pRetNode = errSymbolFind(status)) == NULL) { + *pvalue = -1; + return; + } + strcpy(pname, pRetNode->message); + *pvalue = status; + return; +} + +/**************************************************************** + * ERRSYMFIND + ***************************************************************/ +#ifdef __STDC__ +int errSymFind(long status, char *name) +#else +/* errSymFind - Locate error symbol */ +int errSymFind(status, name) + long status; + char *name; +#endif /* __STDC__ */ +{ + long value; +#ifdef vxWorks + unsigned char type; +#endif + unsigned short modnum; + + if (!initialized) { + printf("\nerrSymFind: Aborting because errSymBld didn't initialize\n"); + return (-1); + } + + modnum = (status >> 16); + if (modnum <= 500) +#ifdef vxWorks + symFindByValue((SYMTAB_ID)statSymTbl, status, name,(int*) &value, (SYM_TYPE*)&type); +#else + UnixSymFind(status, name, &value); +#endif + else + ModSymFind(status, name, &value); + if (value != status) + return (-1); + else + return (0); +} + +/**************************************************************** + * ERRSYMFINDTST + ***************************************************************/ +void errSymFindTst() +{ + ERRNUMNODE *phashtable = hashtable; + ERRNUMNODE *pNextNode; + char message[128]; + unsigned short modnum; + unsigned short errnum; + int i; + + for ( i=0; ierrNum >> 16); + errnum = pNextNode->errNum & 0xffff; + if((errSymFind (pNextNode->errNum, message)) <0 ) + { + printf("errSymFindTst: errSymFind FAILED - modnum=%d errnum=%d\n" + ,modnum ,errnum); + } + printf("hash_no=%d mod=%d num=%d errmess=\"%s\"\n" + , i, modnum, errnum, message); + pNextNode = pNextNode->hashnode; + } + } +return; +} + +/**************************************************************** + * errSymDump + ***************************************************************/ +#ifdef __STDC__ +void errSymDump() +#else +void errSymDump() +#endif /* __STDC__ */ +{ +ERRNUMNODE *phashtable; +ERRNUMNODE *pNextNode; +ERRNUMNODE *pLastNode; +int i; +int modnum; +int errnum; +int msgcount; + + phashtable = hashtable; + msgcount = 0; + printf("\nerrSymDump: HASH NUMBER=%d\n", NHASH); + for ( i=0; i < NHASH; i++) { + if ( (pNextNode = phashtable[i].hashnode) == NULL ) + continue; + printf("\nHASHNODE=%d\n", i); + while (pNextNode) { + modnum = pNextNode->errNum >> 16; + errnum = pNextNode->errNum & 0xffff; + printf("\tmodule=%d errnum=%d\n\tmessage=\"%s\"\n" + , modnum , errnum , pNextNode->message); + msgcount++; + pLastNode = pNextNode; + pNextNode=pNextNode->hashnode; + } + } + printf("\nerrSymDump: total number of error messages=%d\n", msgcount); +}