/* $Id$ * Author: Roger A. Cole * Date: 03-29-90 * * 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: * ----------------- * .00 03-29-90 rac initial version * .01 06-18-91 rac installed in SCCS * .02 01-29-92 rac added wildMatch function * .03 08-11-93 mrk removed ifdef V5_vxWorks * .04 07-06-94 mrk added ifndef VMS for genShellCommand * * make options * -DvxWorks makes a version for VxWorks * -DNDEBUG don't compile assert() checking * -DDEBUG compile various debug code, including checks on * malloc'd memory */ /*+/mod*********************************************************************** * TITLE genSubr.c - some general use routines * * DESCRIPTION * This file contains some routines which are generally useful for * EPICS programs. Some routines are for SunOS vs. VxWorks * compatibility. * * QUICK REFERENCE * assert( expression) * assertAlways( expression) * char *genMalloc( nBytes) * void genBufCheck( pBuf) * void genFree( pBuf) * void genShellCommand(cmdBuf, resultBuf, resultDim) * void genSigInit( pHandler) * int perror( string) * int wildMatch( string, pattern, ignoreCase) * * SEE ALSO * genDefs.h *-***************************************************************************/ #include #ifdef vxWorks # include # include # include # include # include #else # include # include # include #endif /*+/macro********************************************************************* * NAME assert - check assertion * * DESCRIPTION * Checks to see if an expression is true. If the expression is false, * an error message is printed and a signal is raised (SIGABRT or, for * VxWorks, SIGUSR1). * * This is actually a macro provided by genDefs.h . If the preprocessor * symbol NDEBUG is defined, then the expression isn't evaluated or * checked. * * USAGE * assert(expression); * assertAlways(expression); (same as assert(), but isn't disabled * by defining NDEBUG) * * RETURNS * void * * NOTES * 1. Since evaluation of the expression is conditional (depending on * whether NDEBUG is defined), it is poor practice to use expressions * which have side effects. * 2. assertAlways(0) is recommended rather than abort(). * *-*/ /*---------------------------------------------------------------------------- * assertFail - handle assertion failure * For SunOS, call abort(). * For VxWorks, try to deliver a SIGUSR1 signal. If that's not * possible, generate a bus error. *---------------------------------------------------------------------------*/ int assertFail(fileName, lineNum) char *fileName; int lineNum; { (void)fprintf(stderr, "assertFail: in file %s line %d\n", fileName, lineNum); #ifdef vxWorks if (kill(taskIdSelf(), SIGUSR1) == ERROR) { int *j; j = (int *)(-1); j = (int *)(*j); } exit(1); #else abort(); #endif return (0); } /*+/subr********************************************************************** * NAME genMalloc - malloc() and free() 'pre-processor' with "guards" * * DESCRIPTION * These routines support catching overwriting a block of memory * obtained by malloc(). A 'guard' field is added at the beginning * and end of the block of memory when genMalloc() is called to * allocate the block. The 'guard' field is checked by genFree(). * * genMalloc() works the same as malloc(), returning a pointer to * the 'usable' part of the memory block. (I.e., the guard fields are * 'hidden' from the caller.) * * genFree() works the same as free(), except it checks to see if * the guard field has been clobbered. * * A third routine, genBufCheck() allows checking at arbitrary times * (even from dbx) on whether a block has been clobbered. * *****************************************************************************/ #if 0 /* a simple demonstration of usage */ main() { int *x; int i; x = (int *)genMalloc(100); genBufCheck(x); for (i=0; i<26; i++) *(x+i) = i; genFree(x); exit(0); } #endif # define CHK_MALLOC_FILL_PATTERN 1 /*---------------------------------------------------------------------------- * malloc a block with the following layout, with the block and guard * fields aligned on longword boundaries * * longword 0 nLong for block, including this longword and the * 'guard' longwords * longword 1 &longword 0 * user bytes * longword n &longword 0 *---------------------------------------------------------------------------*/ char *genMalloc(nBytes) int nBytes; { long *ptrL; int i; unsigned nLong, sizeC; nLong = 3 + (nBytes+sizeof(long)-1)/sizeof(long); sizeC = nLong * sizeof(long); ptrL = (long *)malloc(sizeC); if (ptrL != NULL) { for (i=0; i * #include (or for VxWorks) * * jmp_buf mySigEnv; * * void myHandler(sigNum) * int sigNum; * { * signal(sigNum, SIG_DFL); * longjmp(mySigEnv, sigNum); * } * * main() * { * int sigNum; * * genSigInit(myHandler); * if ((sigNum = setjmp(mySigEnv)) != 0) * goto sigOccurred; * . * . * exit(0); * sigOccurred: * printf("signal %d detected\n", sigNum); * exit(1); * } * *-*/ void genSigInit(handler) void (* handler)(); /* I pointer to signal handler */ { (void)signal(SIGTERM, handler); /* SunOS plain kill (not -9) */ (void)signal(SIGQUIT, handler); /* SunOS ^\ */ (void)signal(SIGINT, handler); /* SunOS ^C */ (void)signal(SIGILL, handler); /* illegal instruction */ #ifndef vxWorks (void)signal(SIGABRT, handler); /* SunOS assert */ #else (void)signal(SIGUSR1, handler); /* VxWorks assert */ #endif (void)signal(SIGBUS, handler); /* bus error */ (void)signal(SIGSEGV, handler); /* segmentation violation */ (void)signal(SIGFPE, handler); /* arithmetic exception */ (void)signal(SIGPIPE, handler); /* write to disconnected socket */ } int doMatch(); /*+/subr********************************************************************** * NAME wildMatch - do wildcard matching on strings * * DESCRIPTION * Search a text string for a match of a pattern, where the pattern * can contain wildcard characters. * * The wildcard characters and their meanings are: * ? matches any single character * * matches any sequence of zero or more characters * * RETURNS * 1 if a match is obtained, or * 0 * *-*/ int wildMatch(text, p, ignoreCase) char *text; /* I the text to be checked */ char *p; /* I the pattern, possibly with wildcards */ int ignoreCase; /* I 0,1 to honor,ignore upper/lower case differences */ { char *starP=NULL; /* pointer at beginning of * wildcard */ char *starText=NULL; /* pointer at beginning of * wildcard */ int matched; /* char in text matches char in pattern */ char a, b; if (*text == '\0') return 0; while (*p != '\0' && *text != '\0') { switch (*p) { case '*': starP = ++p; if (*p == '\0') return 1; starText = text; break; default: matched = (*text == *p || *p == '?') ? 1 : 0; if (ignoreCase && !matched) { a = *text; b = *p; if (isascii(a) && isascii(b) && isalpha(a) && isalpha(b)) { if (isupper(a)) a = tolower(a); if (isupper(b)) b = tolower(b); if (a == b) matched = 1; } } if (matched) { text++, p++; if (*p == '\0') { if (*text == '\0' || *(p-1) == '*') return 1; text = ++starText; if (starP == NULL) return 0; p = starP; } } else if (starP == NULL) return 0; else { text = ++starText; p = starP; } break; } } if (*text == '\0') { if (*p == '\0') return 1; if (*p != '*') return 0; if (*(++p) == '\0') return 1; } return 0; }