New errlog facility. Replaces old epicsPrintf stuff
This commit is contained in:
@@ -14,6 +14,7 @@ INC += cvtFast.h
|
||||
INC += ellLib.h
|
||||
INC += envDefs.h
|
||||
INC += epicsAssert.h
|
||||
INC += errlog.h
|
||||
INC += epicsPrint.h
|
||||
INC += errMdef.h
|
||||
INC += error.h
|
||||
@@ -28,12 +29,12 @@ INC += fdManager.h
|
||||
INC += osiTime.h
|
||||
INC += osiTimer.h
|
||||
INC += macLib.h
|
||||
INC += impLib.h
|
||||
INC += sigPipeIgnore.h
|
||||
INC += dbmf.h
|
||||
INC += ipAddrToA.h
|
||||
INC += epicsString.h
|
||||
INC += truncateFile.h
|
||||
INC += adjustment.h
|
||||
|
||||
# For WIN32 we supply getopt as part of libCom:
|
||||
INC_WIN32 := getopt.h
|
||||
@@ -50,7 +51,7 @@ LIBSRCS += cvtFast.c
|
||||
LIBSRCS += ellLib.c
|
||||
LIBSRCS += envSubr.c
|
||||
LIBSRCS += envData.c
|
||||
LIBSRCS += errPrintfUNIX.c
|
||||
LIBSRCS += errlogUNIX.c
|
||||
LIBSRCS += errSymLib.c
|
||||
LIBSRCS += errSymTbl.c
|
||||
LIBSRCS += fdmgr.c
|
||||
@@ -62,7 +63,6 @@ LIBSRCS += postfix.c
|
||||
LIBSRCS += realpath.c
|
||||
LIBSRCS += tsSubr.c
|
||||
LIBSRCS += assertUNIX.c
|
||||
LIBSRCS += impLib.c
|
||||
LIBSRCS += macCore.c
|
||||
LIBSRCS += macUtil.c
|
||||
LIBSRCS += sigPipeIgnore.c
|
||||
@@ -71,6 +71,7 @@ LIBSRCS += ipAddrToA.c
|
||||
LIBSRCS += epicsString.c
|
||||
LIBSRCS += truncateFile.c
|
||||
LIBSRCS += aToIPAddr.c
|
||||
LIBSRCS += adjustment.c
|
||||
|
||||
#
|
||||
# if CPLUSPLUS isnt empty then include C++ src codes
|
||||
@@ -103,7 +104,6 @@ PROD_LIBS = Com
|
||||
#TESTPROD=tsTest
|
||||
#TESTPROD=envtest
|
||||
#TESTPROD=osiTimeTest fdManagerTest
|
||||
PROD = impExpand
|
||||
|
||||
MAN3 = gpHash.3 freeList.3
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ SRCS.c += ../tsSubr.c
|
||||
SRCS.c += ../pal.c
|
||||
SRCS.c += ../paldef.c
|
||||
SRCS.c += errSymTbl.c
|
||||
SRCS.c += ../errPrintfVX.c
|
||||
SRCS.c += ../errlogVX.c
|
||||
SRCS.c += ../assertVX.c
|
||||
SRCS.c += ../macCore.c
|
||||
SRCS.c += ../macUtil.c
|
||||
@@ -29,10 +29,10 @@ SRCS.c += ../macUtil.c
|
||||
#SRCS.c += ../os/vxWorks/osdTime.cc
|
||||
SRCS.c += ../os/vxWorks/ipAddrToA.c
|
||||
SRCS.c += ../os/vxWorks/sigPipeIgnore.c
|
||||
SRCS.c += ../impLib.c
|
||||
SRCS.c += ../dbmf.c
|
||||
SRCS.c += ../epicsString.c
|
||||
SRCS.c += ../aToIPAddr.c
|
||||
SRCS.c += ../adjustment.c
|
||||
|
||||
LIBOBJS += calcPerform.o
|
||||
LIBOBJS += cvtFast.o
|
||||
@@ -49,7 +49,7 @@ LIBOBJS += gpHashLib.o
|
||||
LIBOBJS += freeListLib.o
|
||||
LIBOBJS += pal.o
|
||||
LIBOBJS += paldef.o
|
||||
LIBOBJS += errPrintfVX.o
|
||||
LIBOBJS += errlogVX.o
|
||||
LIBOBJS += assertVX.o
|
||||
LIBOBJS += macCore.o
|
||||
LIBOBJS += macUtil.o
|
||||
@@ -57,10 +57,10 @@ LIBOBJS += macUtil.o
|
||||
#LIBOBJS += osdTime.o
|
||||
LIBOBJS += ipAddrToA.o
|
||||
LIBOBJS += sigPipeIgnore.o
|
||||
LIBOBJS += impLib.o
|
||||
LIBOBJS += dbmf.o
|
||||
LIBOBJS += epicsString.o
|
||||
LIBOBJS += aToIPAddr.o
|
||||
LIBOBJS += adjustment.o
|
||||
|
||||
LIBNAME = libCom
|
||||
|
||||
|
||||
@@ -1,34 +1,9 @@
|
||||
/*epicsPrint.h */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#define epicsPrintUseProtoANSI
|
||||
#endif
|
||||
/*This is now obsolete. Remlaced by errlog.h */
|
||||
#ifndef INCepicsPrintH
|
||||
#define INCepicsPrintH
|
||||
|
||||
#ifdef __STDC__
|
||||
#ifndef epicsPrintUseProtoANSI
|
||||
#define epicsPrintUseProtoANSI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef vxWorks
|
||||
# ifdef epicsPrintUseProtoANSI
|
||||
# include <stdarg.h>
|
||||
int epicsPrintf(const char *pFormat, ...);
|
||||
int epicsVprintf (const char *pFormat, va_list pvar);
|
||||
int iocLogVPrintf(const char *pFormat, va_list pvar);
|
||||
int iocLogPrintf(const char *pFormat, ...);
|
||||
# else /* not epicsPrintUseProtoANSI */
|
||||
int epicsPrintf();
|
||||
int epicsVprintf ();
|
||||
int iocLogVPrintf();
|
||||
int iocLogPrintf();
|
||||
# endif /* ifdef epicsPrintUseProtoANSI */
|
||||
#else /* not vxWorks */
|
||||
# define epicsPrintf printf
|
||||
# define epicsVprintf vprintf
|
||||
#endif /* ifdef vxWorks */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include "errlog.h"
|
||||
|
||||
#endif /*INCepicsPrintH*/
|
||||
|
||||
@@ -61,6 +61,10 @@ extern "C" {
|
||||
#include "ellLib.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
/*The following is only included because before 3.13.0beta12 errMessage */
|
||||
/*and errPrintf were defined here */
|
||||
#include "errlog.h"
|
||||
|
||||
#define RTN_SUCCESS(STATUS) ((STATUS)==0)
|
||||
|
||||
#define M_dbAccess (501 <<16) /*Database Access Routines */
|
||||
@@ -88,13 +92,6 @@ extern "C" {
|
||||
#define M_bucket (525 <<16) /*Bucket Hash*/
|
||||
#define M_gddFuncTbl (526 <<16) /*gdd jump table*/
|
||||
|
||||
/*
|
||||
* redefine errMessage with a macro so we can print
|
||||
* the file and line number
|
||||
*/
|
||||
#define errMessage(S, PM) \
|
||||
errPrintf(S, __FILE__, __LINE__, PM)
|
||||
|
||||
#ifdef errMDefUseProtoANSI
|
||||
epicsShareFunc int epicsShareAPI errSymFind(long status, char *name);
|
||||
epicsShareFunc int epicsShareAPI UnixSymFind(long status, char *name, long *value);
|
||||
@@ -103,11 +100,8 @@ epicsShareFunc void epicsShareAPI errSymTest(unsigned short modnum, unsigned sho
|
||||
epicsShareFunc void epicsShareAPI errSymTestPrint(long errNum);
|
||||
epicsShareFunc int epicsShareAPI errSymBld();
|
||||
epicsShareFunc int epicsShareAPI errSymbolAdd (long errNum,char *name);
|
||||
epicsShareFunc void epicsShareAPI errPrintf(long status, const char *pFileName,
|
||||
int lineno, const char *pformat, ...);
|
||||
epicsShareFunc void epicsShareAPI errSymDump();
|
||||
epicsShareFunc void epicsShareAPI tstErrSymFind();
|
||||
epicsShareFunc void epicsShareAPI errInit(void);
|
||||
|
||||
#else /* errMDefUseProtoANSI */
|
||||
|
||||
@@ -118,7 +112,6 @@ epicsShareFunc int epicsShareAPI ModSymFind();
|
||||
epicsShareFunc void epicsShareAPI errSymTestPrint();
|
||||
epicsShareFunc int epicsShareAPI errSymBld();
|
||||
epicsShareFunc int epicsShareAPI errSymbolAdd();
|
||||
epicsShareFunc void epicsShareAPI errPrintf();
|
||||
epicsShareFunc void epicsShareAPI errSymDump();
|
||||
epicsShareFunc void epicsShareAPI tstErrSymFind();
|
||||
#endif /* errMDefUseProtoANSI */
|
||||
|
||||
95
src/libCom/errlog.h
Normal file
95
src/libCom/errlog.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* src/libCom/errlog.h */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef INCerrlogh
|
||||
#define INCerrlogh
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#define epicsPrintUseProtoANSI
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
#ifndef epicsPrintUseProtoANSI
|
||||
#define epicsPrintUseProtoANSI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* define errMessage with a macro so we can print the file and line number*/
|
||||
#define errMessage(S, PM) \
|
||||
errPrintf(S, __FILE__, __LINE__, PM)
|
||||
/* epicsPrintf and epicsVprintf old versions of errlog routines*/
|
||||
#define epicsPrintf errlogPrintf
|
||||
#define epicsVprintf errlogVprintf
|
||||
|
||||
typedef void(*errlogListener) (const char *message);
|
||||
typedef enum {errlogInfo,errlogMinor,errlogMajor,errlogFatal} errlogSevEnum;
|
||||
extern char * errlogSevEnumString[];
|
||||
#ifdef ERRLOG_INIT
|
||||
char * errlogSevEnumString[] = {"info","minor","major","fatal"};
|
||||
#endif
|
||||
|
||||
#ifdef epicsPrintUseProtoANSI
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogPrintf(
|
||||
const char *pformat, ...);
|
||||
epicsShareFunc int epicsShareAPI errlogVprintf(
|
||||
const char *pformat,va_list pvar);
|
||||
epicsShareFunc int epicsShareAPI errlogSevPrintf(
|
||||
const errlogSevEnum severity,const char *pformat, ...);
|
||||
epicsShareFunc int epicsShareAPI errlogSevVprintf(
|
||||
const errlogSevEnum severity,const char *pformat,va_list pvar);
|
||||
epicsShareFunc int epicsShareAPI errlogMessage(
|
||||
const char *message);
|
||||
|
||||
epicsShareFunc char * epicsShareAPI errlogGetSevEnumString(
|
||||
const errlogSevEnum severity);
|
||||
epicsShareFunc void epicsShareAPI errlogSetSevToLog(
|
||||
const errlogSevEnum severity );
|
||||
epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog(void);
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogAddListener(
|
||||
errlogListener listener);
|
||||
epicsShareFunc void epicsShareAPI errlogRemoveListener(
|
||||
errlogListener listener);
|
||||
|
||||
epicsShareFunc void epicsShareAPI eltc(int yesno);
|
||||
epicsShareFunc void epicsShareAPI errlogInit(int bufsize);
|
||||
|
||||
/*other routines that write to log file*/
|
||||
epicsShareFunc void epicsShareAPI errPrintf(long status, const char *pFileName,
|
||||
int lineno, const char *pformat, ...);
|
||||
|
||||
#else /* not epicsPrintUseProtoANSI */
|
||||
epicsShareFunc int epicsShareAPI errlogPrintf();
|
||||
epicsShareFunc int epicsShareAPI errlogVprintf();
|
||||
epicsShareFunc int epicsShareAPI errlogSevPrintf();
|
||||
epicsShareFunc int epicsShareAPI errlogSevVprintf();
|
||||
epicsShareFunc int epicsShareAPI errlogMessage();
|
||||
epicsShareFunc char * epicsShareAPI errlogGetSevEnumString();
|
||||
epicsShareFunc void epicsShareAPI errlogSetSevToLog();
|
||||
epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog();
|
||||
epicsShareFunc void epicsShareAPI errlogAddListener();
|
||||
epicsShareFunc void epicsShareAPI errlogRemoveListener();
|
||||
epicsShareFunc void epicsShareAPI eltc();
|
||||
epicsShareFunc void epicsShareAPI errlogInit();
|
||||
epicsShareFunc void epicsShareAPI errPrintf();
|
||||
#endif /* ifdef epicsPrintUseProtoANSI */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*INCerrlogh*/
|
||||
152
src/libCom/errlog.html
Normal file
152
src/libCom/errlog.html
Normal file
@@ -0,0 +1,152 @@
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||
<META NAME="GENERATOR" CONTENT="Mozilla/4.03 [en] (X11; U; SunOS 5.5.1 sun4u) [Netscape]">
|
||||
</HEAD>
|
||||
<BODY>
|
||||
|
||||
<H1>
|
||||
Error Logging System</H1>
|
||||
The error logging system provides:
|
||||
<UL>
|
||||
<LI>
|
||||
Error message routines that can be called by ioc code.</LI>
|
||||
|
||||
<LI>
|
||||
Provision for multiple system wide error loggers..</LI>
|
||||
|
||||
<LI>
|
||||
A task (errlog) that handles the messages generated by the client routines.
|
||||
It displays messages on the target console and also gives them to any registered
|
||||
system wide error loggers.</LI>
|
||||
|
||||
<LI>
|
||||
iocLog: A system wide error logger that writes all error message to a file.</LI>
|
||||
</UL>
|
||||
|
||||
<H2>
|
||||
Overview</H2>
|
||||
|
||||
<UL>
|
||||
<LI>
|
||||
The error message routines can be called by any non-interrupt level code.</LI>
|
||||
|
||||
<LI>
|
||||
Task errlog manages the messages. Messages are placed in a message queue,
|
||||
which is read by the errlog task. The message queue uses a fixed block
|
||||
of memory to hold all messages. When the message queue is full additional
|
||||
messages are rejected but a count of missed messages is kept. The next
|
||||
time the message queue empties an extra message about the missed messages
|
||||
is generated.</LI>
|
||||
|
||||
<LI>
|
||||
The maximum message size is 256 characters. If a message is
|
||||
longer, the message is truncated and a message explaining that it was truncated
|
||||
is appended. There is a chance that long messages corrupt memory. This
|
||||
only happens if client code is defective. Long messages most likely result
|
||||
from "%s" formats with a bad string argument.</LI>
|
||||
|
||||
<LI>
|
||||
The error message routines are partially implemented on the host. The host
|
||||
version just calls fprintf or vfprintf instead of using a separate task
|
||||
and a message queue. Thus host messages are NOT sent to a system wide error
|
||||
logger.</LI>
|
||||
</UL>
|
||||
|
||||
<H2>
|
||||
Client Routines</H2>
|
||||
<I>Basic Routines</I>
|
||||
<UL>
|
||||
<PRE>typedef enum {
|
||||
errlogInfo,errlogMinor,errlogMajor,errlogFatal
|
||||
}errlogSevEnum;
|
||||
|
||||
int errlogPrintf(const char *pformat, ...);
|
||||
int errlogVprintf(const char *pformat,va_list pvar);
|
||||
|
||||
int errlogSevPrintf(const errlogSevEnum severity,
|
||||
const char *pformat, ...);
|
||||
int errlogSevVprintf(const errlogSevEnum severity,
|
||||
const char *pformat,va_list pvar);
|
||||
|
||||
int errlogMessage( const char *message);
|
||||
|
||||
char * errlogGetSevEnumString(const errlogSevEnum severity);
|
||||
|
||||
void errlogSetSevToLog(const errlogSevEnum severity );
|
||||
errlogSevEnum errlogGetSevToLog(void);</PRE>
|
||||
These are the basic client routines.
|
||||
|
||||
<P>errlogPrintf and errlogVprintf act just like printf and vprintf.
|
||||
|
||||
<P>errlogSevPrintf and errlogSevVprintf are similar except that they also
|
||||
add the severity to the beginning of the message in the form "sevr=<value>"
|
||||
where value is on of "info, minor, major, fatal". Also the message is suppressed
|
||||
if severity is less than the current severity to suppress.
|
||||
|
||||
<P>errlogMessage just logs message.
|
||||
|
||||
<P>errlogGetSevEnumString gets the string value of severity.
|
||||
|
||||
<P>errlogSetSevToLog sets the severity to log. errlogGetSevToLog gets the
|
||||
current severity to log.</UL>
|
||||
<I>Status Routines</I>
|
||||
<BR>
|
||||
<UL>
|
||||
<PRE>void errMessage(long status, char *message);</PRE>
|
||||
|
||||
<PRE>void errPrintf(long status, const char *pFileName,
|
||||
int lineno, const char *pformat, ...);</PRE>
|
||||
errMessage is just a macro that calls errPrintf. errPrintf is meant to
|
||||
be called as follows:
|
||||
<PRE> errPrintf(status,__FILE__, __LINE__,"<format>",...)</PRE>
|
||||
The argument status is described in the Application Developer's guide.
|
||||
The arguments __FILE__ and __LINE__ are standard C preprocessor variables.
|
||||
<BR> </UL>
|
||||
<I>Obsolete Routines</I>
|
||||
<UL>
|
||||
<PRE>int epicsPrintf(const char *pformat, ...);
|
||||
int epicsVprintf(const char *pformat,va_list pvar);</PRE>
|
||||
These are exactly like errlogPrintf and errlogVprintf. They are provided
|
||||
because a lot of existing code calls them,. </UL>
|
||||
<I>Add and Remove Log Listener</I>
|
||||
<UL>
|
||||
<PRE>typedef void(*errlogListener) (const char *message);
|
||||
void errlogAddListener(errlogListener listener);
|
||||
void errlogRemoveListener(errlogListener listener);</PRE>
|
||||
These routines add/remove a callback that receives each error message.
|
||||
<BR> </UL>
|
||||
<I>target console routines</I>
|
||||
<UL>
|
||||
<PRE>void eltc(int yesno); /* error log to console (0 or 1) */
|
||||
void errlogInit(int bufsize);</PRE>
|
||||
</UL>
|
||||
eltc determines if errlog task writes message to the console. If error
|
||||
messages storms are occuring the command can be used to suppress the messages.
|
||||
A argument of 0 suppresses the messages and any other value lets the message
|
||||
go to the console.
|
||||
|
||||
<P>errlogInit can be used to initialize the error logging system with a
|
||||
larger buffer. The default is 1280 bytes. An extra MAX_MESSAGE_SIZE (currently
|
||||
256) bytes are allocated but never used. This is a small extra protection
|
||||
against long error messages.
|
||||
<H1>
|
||||
iocLog</H1>
|
||||
This consists of two modules: iocLogServer and iocLogClient. The client
|
||||
code runs on each ioc and listens for the messages generated by the errlog
|
||||
system. It also reports the messages from vxWorks logMsg.
|
||||
<H3>
|
||||
iocLogServer</H3>
|
||||
This runs on a host. It receives messages for all enabled iocLogClients
|
||||
in the local area network. The messages are written to a file. Epics base
|
||||
provides a startup file "base/src/util/rc2.logServer", which is a shell
|
||||
script to start the server. Consult this script for details.
|
||||
<H3>
|
||||
iocLogClient</H3>
|
||||
This runs on each ioc. It is started by default when iocInit runs. The
|
||||
global variable iocLogDisable can be used to enable/disable the messages
|
||||
from being sent to the server. Setting this variable to (0,1) (enables,disables)
|
||||
the messages generation. If iocLogDisable<TT> </TT>is set to 1 immediately
|
||||
after iocCore is loaded then iocLogClient will not even initialize itself.
|
||||
</BODY>
|
||||
</HTML>
|
||||
174
src/libCom/errlogUNIX.c
Normal file
174
src/libCom/errlogUNIX.c
Normal file
@@ -0,0 +1,174 @@
|
||||
/* $Id$
|
||||
* errPrintfUNIX.c
|
||||
* Author: Marty Kraimer
|
||||
* Date: 02-16-95
|
||||
*
|
||||
* 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: errPrintfUNIX.c
|
||||
* -----------------
|
||||
* .01 02-16-95 mrk Extracted from errSymLib.c
|
||||
***************************************************************************
|
||||
* 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 call fprintf and vfprintf
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "epicsAssert.h"
|
||||
#define epicsExportSharedSymbols
|
||||
#define ERRLOG_INIT
|
||||
#include "errlog.h"
|
||||
#undef ERRLOG_INIT
|
||||
#undef epicsExportSharedSymbols
|
||||
|
||||
#include "errMdef.h"
|
||||
#include "error.h"
|
||||
|
||||
|
||||
static int sevToLog=0;
|
||||
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogPrintf(const char *pformat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
int nchar;
|
||||
|
||||
va_start(pvar,pformat);
|
||||
nchar = errlogVprintf(pformat,pvar);
|
||||
va_end (pvar);
|
||||
return(nchar);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogVprintf(
|
||||
const char *pformat, va_list pvar)
|
||||
{
|
||||
return(vfprintf(stderr,pformat,pvar));
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogMessage(const char *message)
|
||||
{
|
||||
fprintf(stderr,"%s\n",message);
|
||||
return(0);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogSevPrintf(
|
||||
const errlogSevEnum severity,const char *pformat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
int nchar;
|
||||
|
||||
if(sevToLog>severity) return(0);
|
||||
va_start(pvar, pformat);
|
||||
nchar = errlogSevVprintf(severity,pformat,pvar);
|
||||
va_end (pvar);
|
||||
return(nchar);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogSevVprintf(
|
||||
const errlogSevEnum severity,const char *pformat,va_list pvar)
|
||||
{
|
||||
char *pnext;
|
||||
int nchar;
|
||||
int totalChar=0;
|
||||
|
||||
if(sevToLog>severity) return(0);
|
||||
fprintf(stderr,"sevr=%s ",errlogGetSevEnumString(severity));
|
||||
nchar = vfprintf(stderr,pformat,pvar);
|
||||
fprintf(stderr,"\n");
|
||||
return(nchar+1);
|
||||
}
|
||||
|
||||
epicsShareFunc char * epicsShareAPI errlogGetSevEnumString(
|
||||
const errlogSevEnum severity)
|
||||
{
|
||||
static char unknown[] = "unknown";
|
||||
|
||||
if(severity<0 || severity>3) return(unknown);
|
||||
return(errlogSevEnumString[severity]);
|
||||
}
|
||||
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogSetSevToLog(
|
||||
const errlogSevEnum severity )
|
||||
{
|
||||
sevToLog = severity;
|
||||
}
|
||||
|
||||
epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog()
|
||||
{
|
||||
return(sevToLog);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogAddListener(
|
||||
errlogListener listener)
|
||||
{
|
||||
fprintf(stderr,"errlogAddListener not implemented\n");
|
||||
return;
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogRemoveListener(
|
||||
errlogListener listener)
|
||||
{
|
||||
fprintf(stderr,"errlogRemoveListener not implemented\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
epicsShareFunc void epicsShareAPI errPrintf(long status, const char *pFileName,
|
||||
int lineno, const char *pformat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
|
||||
va_start(pvar, pformat);
|
||||
if(pFileName && errVerbose){
|
||||
fprintf(stderr,"filename=\"%s\" line number=%d\n", pFileName, lineno);
|
||||
}
|
||||
if(status==0) status = errno;
|
||||
if(status>0) {
|
||||
int rtnval;
|
||||
char name[256];
|
||||
|
||||
rtnval = errSymFind(status,name);
|
||||
if(rtnval) {
|
||||
unsigned short modnum,errnum;
|
||||
|
||||
modnum = (unsigned short) (status >> 16);
|
||||
errnum = (unsigned short) (status & 0xffff);
|
||||
fprintf(stderr, "status (%hu,%hu) not in symbol table",
|
||||
modnum, errnum);
|
||||
} else {
|
||||
fprintf(stderr,"%s ",name);
|
||||
}
|
||||
}
|
||||
if (pformat) {
|
||||
vfprintf(stderr,pformat,pvar);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
479
src/libCom/errlogVX.c
Normal file
479
src/libCom/errlogVX.c
Normal file
@@ -0,0 +1,479 @@
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
/*
|
||||
* Author: Marty Kraimer and Jeff Hill
|
||||
* Date: 07JAN1998
|
||||
* NOTE: Original version is adaptation of old version of errPrintfVX.c
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <taskLib.h>
|
||||
#include <intLib.h>
|
||||
#include <semLib.h>
|
||||
#include <vxLib.h>
|
||||
#include <errnoLib.h>
|
||||
#include <logLib.h>
|
||||
|
||||
#include "epicsAssert.h"
|
||||
#define epicsExportSharedSymbols
|
||||
#define ERRLOG_INIT
|
||||
#include "errlog.h"
|
||||
#undef ERRLOG_INIT
|
||||
#undef epicsExportSharedSymbols
|
||||
#include "errMdef.h"
|
||||
#include "ellLib.h"
|
||||
#include "error.h"
|
||||
#include "task_params.h"
|
||||
|
||||
#ifndef LOCAL
|
||||
#define LOCAL static
|
||||
#endif /* LOCAL */
|
||||
|
||||
#define BUFFER_SIZE 1280
|
||||
#define MAX_MESSAGE_SIZE 256
|
||||
#define TRUNCATE_SIZE 80
|
||||
#define MAX_ALIGNMENT 8
|
||||
|
||||
LOCAL void errlogTask(void);
|
||||
|
||||
LOCAL char *msgbufGetFree(void);
|
||||
LOCAL void msgbufSetSize(int size);
|
||||
LOCAL char * msgbufGetSend(void);
|
||||
LOCAL void msgbufFreeSend(void);
|
||||
|
||||
LOCAL void *pvtCalloc(size_t count,size_t size);
|
||||
LOCAL void pvtSemTake(SEM_ID semid);
|
||||
|
||||
typedef struct listenerNode{
|
||||
ELLNODE node;
|
||||
errlogListener listener;
|
||||
}listenerNode;
|
||||
|
||||
/*each message consists of a msgNode immediately followed by the message */
|
||||
typedef struct msgNode {
|
||||
ELLNODE node;
|
||||
char *message;
|
||||
int length;
|
||||
} msgNode;
|
||||
|
||||
LOCAL struct {
|
||||
SEM_ID errlogTaskWaitForWork;
|
||||
SEM_ID msgQueueLock;
|
||||
SEM_ID listenerLock;
|
||||
ELLLIST listenerList;
|
||||
ELLLIST msgQueue;
|
||||
msgNode *pnextSend;
|
||||
int buffersize;
|
||||
int sevToLog;
|
||||
int toConsole;
|
||||
int missedMessages;
|
||||
void *pbuffer;
|
||||
}pvtData;
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogPrintf( const char *pFormat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
int nchar;
|
||||
|
||||
if(INT_CONTEXT()) {
|
||||
logMsg("errlogPrintf called from interrupt level\n",0,0,0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
va_start(pvar, pFormat);
|
||||
nchar = errlogVprintf(pFormat,pvar);
|
||||
va_end (pvar);
|
||||
return(nchar);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogVprintf(
|
||||
const char *pFormat,va_list pvar)
|
||||
{
|
||||
int nchar;
|
||||
char *pbuffer;
|
||||
|
||||
if(INT_CONTEXT()) {
|
||||
logMsg("errlogVprintf called from interrupt level\n",0,0,0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
pbuffer = msgbufGetFree();
|
||||
if(!pbuffer) return(0);
|
||||
nchar = vsprintf(pbuffer,pFormat,pvar);
|
||||
msgbufSetSize(nchar+1);/*include the \0*/
|
||||
return nchar;
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogMessage(const char *message)
|
||||
{
|
||||
int status;
|
||||
char *pbuffer;
|
||||
|
||||
if(INT_CONTEXT()) {
|
||||
status = logMsg ("errlogMessage called from interrupt level %s",
|
||||
message,0,0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
pbuffer = msgbufGetFree();
|
||||
if(!pbuffer) return(0);
|
||||
strcpy(pbuffer,message);
|
||||
msgbufSetSize(strlen(message) +1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogSevPrintf(
|
||||
const errlogSevEnum severity,const char *pFormat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
int nchar;
|
||||
|
||||
if(INT_CONTEXT()) {
|
||||
logMsg("errlogSevPrintf called from interrupt level\n",0,0,0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
if(pvtData.sevToLog>severity) return(0);
|
||||
va_start(pvar, pFormat);
|
||||
nchar = errlogSevVprintf(severity,pFormat,pvar);
|
||||
va_end (pvar);
|
||||
return(nchar);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogSevVprintf(
|
||||
const errlogSevEnum severity,const char *pFormat,va_list pvar)
|
||||
{
|
||||
char *pnext;
|
||||
int nchar;
|
||||
int totalChar=0;
|
||||
|
||||
if(pvtData.sevToLog>severity) return(0);
|
||||
if(INT_CONTEXT()) {
|
||||
logMsg("errlogSevVprintf called from interrupt level\n",0,0,0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
pnext = msgbufGetFree();
|
||||
if(!pnext) return(0);
|
||||
nchar = sprintf(pnext,"sevr=%s ",errlogGetSevEnumString(severity));
|
||||
pnext += nchar; totalChar += nchar;
|
||||
nchar = vsprintf(pnext,pFormat,pvar);
|
||||
pnext += nchar; totalChar += nchar;
|
||||
sprintf(pnext,"\n");
|
||||
totalChar += 2; /*include \n and \0*/
|
||||
msgbufSetSize(totalChar);
|
||||
return(nchar);
|
||||
}
|
||||
|
||||
epicsShareFunc char * epicsShareAPI errlogGetSevEnumString(
|
||||
const errlogSevEnum severity)
|
||||
{
|
||||
static char unknown[] = "unknown";
|
||||
|
||||
errlogInit(0);
|
||||
if(severity<0 || severity>3) return(unknown);
|
||||
return(errlogSevEnumString[severity]);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogSetSevToLog(
|
||||
const errlogSevEnum severity )
|
||||
{
|
||||
errlogInit(0);
|
||||
pvtData.sevToLog = severity;
|
||||
}
|
||||
|
||||
epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog()
|
||||
{
|
||||
errlogInit(0);
|
||||
return(pvtData.sevToLog);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogAddListener(
|
||||
errlogListener listener)
|
||||
{
|
||||
listenerNode *plistenerNode;
|
||||
|
||||
errlogInit(0);
|
||||
plistenerNode = pvtCalloc(1,sizeof(listenerNode));
|
||||
pvtSemTake(pvtData.listenerLock);
|
||||
plistenerNode->listener = listener;
|
||||
ellAdd(&pvtData.listenerList,&plistenerNode->node);
|
||||
semGive(pvtData.listenerLock);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogRemoveListener(
|
||||
errlogListener listener)
|
||||
{
|
||||
listenerNode *plistenerNode;
|
||||
|
||||
errlogInit(0);
|
||||
pvtSemTake(pvtData.listenerLock);
|
||||
plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
|
||||
while(plistenerNode) {
|
||||
if(plistenerNode->listener==listener) {
|
||||
ellDelete(&pvtData.listenerList,&plistenerNode->node);
|
||||
free((void *)plistenerNode);
|
||||
break;
|
||||
}
|
||||
plistenerNode = (listenerNode *)ellNext(&plistenerNode->node);
|
||||
}
|
||||
semGive(pvtData.listenerLock);
|
||||
if(!plistenerNode) printf("errlogRemoveListener did not find listener\n");
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI eltc(int yesno)
|
||||
{
|
||||
errlogInit(0);
|
||||
pvtData.toConsole = yesno;
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errPrintf(long status, const char *pFileName,
|
||||
int lineno, const char *pformat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
char *pnext;
|
||||
int nchar;
|
||||
int totalChar=0;
|
||||
|
||||
if(INT_CONTEXT()) {
|
||||
logMsg("errPrintf called from interrupt level\n",0,0,0,0,0,0);
|
||||
return;
|
||||
}
|
||||
errlogInit(0);
|
||||
pnext = msgbufGetFree();
|
||||
if(!pnext) return;
|
||||
if(pFileName){
|
||||
nchar = sprintf(pnext,"filename=\"%s\" line number=%d\n",
|
||||
pFileName, lineno);
|
||||
pnext += nchar; totalChar += nchar;
|
||||
}
|
||||
if(status==0) status = MYERRNO;
|
||||
if(status>0) {
|
||||
int rtnval;
|
||||
char name[256];
|
||||
|
||||
rtnval = errSymFind(status,name);
|
||||
if(rtnval) {
|
||||
unsigned short modnum,errnum;
|
||||
|
||||
modnum = status >> 16; errnum = status & 0xffff;
|
||||
nchar = sprintf(pnext, "status (%hu,%hu) not in symbol table ",
|
||||
modnum, errnum);
|
||||
} else {
|
||||
nchar = sprintf(pnext,"%s ",name);
|
||||
}
|
||||
pnext += nchar; totalChar += nchar;
|
||||
}
|
||||
va_start (pvar, pformat);
|
||||
nchar = vsprintf(pnext,pformat,pvar);
|
||||
va_end (pvar);
|
||||
if(nchar>0) {
|
||||
pnext += nchar;
|
||||
totalChar += nchar;
|
||||
}
|
||||
sprintf(pnext,"\n");
|
||||
totalChar += 2; /*include the \n and the \0*/
|
||||
msgbufSetSize(totalChar);
|
||||
}
|
||||
|
||||
#define optionsSemM SEM_Q_PRIORITY|SEM_DELETE_SAFE|SEM_INVERSION_SAFE
|
||||
epicsShareFunc void epicsShareAPI errlogInit(int bufsize)
|
||||
{
|
||||
static int errlogInitFlag=0;
|
||||
void *pbuffer;;
|
||||
|
||||
if(!vxTas(&errlogInitFlag)) return;
|
||||
if(bufsize<BUFFER_SIZE) bufsize = BUFFER_SIZE;
|
||||
pvtData.buffersize = bufsize;
|
||||
ellInit(&pvtData.listenerList);
|
||||
ellInit(&pvtData.msgQueue);
|
||||
pvtData.toConsole = TRUE;
|
||||
if((pvtData.errlogTaskWaitForWork=semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL) {
|
||||
logMsg("semBCreate failed in errlogInit",0,0,0,0,0,0);
|
||||
taskSuspend(0);
|
||||
}
|
||||
if((pvtData.listenerLock=semMCreate(optionsSemM))==NULL) {
|
||||
logMsg("semMCreate failed in errlogInit",0,0,0,0,0,0);
|
||||
taskSuspend(0);
|
||||
}
|
||||
if((pvtData.msgQueueLock=semMCreate(optionsSemM))==NULL) {
|
||||
logMsg("semMCreate failed in errlogInit",0,0,0,0,0,0);
|
||||
taskSuspend(0);
|
||||
}
|
||||
/*Allow an extra MAX_MESSAGE_SIZE for extra margain of safety*/
|
||||
pbuffer = pvtCalloc(pvtData.buffersize+MAX_MESSAGE_SIZE,sizeof(char));
|
||||
pvtData.pbuffer = pbuffer;
|
||||
taskSpawn(ERRLOG_NAME,ERRLOG_PRI,ERRLOG_OPT,
|
||||
ERRLOG_STACK,(FUNCPTR)errlogTask,
|
||||
0,0,0,0,0,0,0,0,0,0);
|
||||
}
|
||||
|
||||
LOCAL void errlogTask(void)
|
||||
{
|
||||
listenerNode *plistenerNode;
|
||||
|
||||
while(TRUE) {
|
||||
char *pmessage;
|
||||
|
||||
pvtSemTake(pvtData.errlogTaskWaitForWork);
|
||||
while((pmessage = msgbufGetSend())) {
|
||||
pvtSemTake(pvtData.listenerLock);
|
||||
if(pvtData.toConsole) printf("%s",pmessage);
|
||||
plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
|
||||
while(plistenerNode) {
|
||||
(*plistenerNode->listener)(pmessage);
|
||||
plistenerNode = (listenerNode *)ellNext(&plistenerNode->node);
|
||||
}
|
||||
semGive(pvtData.listenerLock);
|
||||
msgbufFreeSend();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOCAL msgNode *msgbufGetNode()
|
||||
{
|
||||
char *pbuffer = (char *)pvtData.pbuffer;
|
||||
msgNode *pnextSend = 0;
|
||||
|
||||
if(ellCount(&pvtData.msgQueue) == 0 ) {
|
||||
pnextSend = (msgNode *)pbuffer;
|
||||
} else {
|
||||
int needed;
|
||||
int remaining;
|
||||
msgNode *plast;
|
||||
|
||||
plast = (msgNode *)ellLast(&pvtData.msgQueue);
|
||||
needed = MAX_MESSAGE_SIZE + sizeof(msgNode) + MAX_ALIGNMENT;
|
||||
remaining = pvtData.buffersize
|
||||
- ((plast->message - pbuffer) + plast->length);
|
||||
if(needed < remaining) {
|
||||
int length,adjust;
|
||||
|
||||
length = plast->length;
|
||||
/*Make length a multiple of MAX_ALIGNMENT*/
|
||||
adjust = length%MAX_ALIGNMENT;
|
||||
if(adjust) length += (MAX_ALIGNMENT-adjust);
|
||||
pnextSend = (msgNode *)(plast->message + length);
|
||||
}
|
||||
}
|
||||
if(!pnextSend) return(0);
|
||||
pnextSend->message = (char *)pnextSend + sizeof(msgNode);
|
||||
pnextSend->length = 0;
|
||||
return(pnextSend);
|
||||
}
|
||||
|
||||
LOCAL char *msgbufGetFree()
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
pvtSemTake(pvtData.msgQueueLock);
|
||||
if((ellCount(&pvtData.msgQueue) == 0) && pvtData.missedMessages) {
|
||||
int nchar;
|
||||
|
||||
pnextSend = msgbufGetNode();
|
||||
nchar = sprintf(pnextSend->message,"errlog = %d messages were discarded\n",
|
||||
pvtData.missedMessages);
|
||||
pnextSend->length = nchar + 1;
|
||||
pvtData.missedMessages = 0;
|
||||
ellAdd(&pvtData.msgQueue,&pnextSend->node);
|
||||
}
|
||||
pvtData.pnextSend = pnextSend = msgbufGetNode();
|
||||
if(pnextSend) return(pnextSend->message);
|
||||
++pvtData.missedMessages;
|
||||
semGive(pvtData.msgQueueLock);
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL void msgbufSetSize(int size)
|
||||
{
|
||||
char *pbuffer = (char *)pvtData.pbuffer;
|
||||
msgNode *pnextSend = pvtData.pnextSend;
|
||||
char *message = pnextSend->message;
|
||||
|
||||
if(size>MAX_MESSAGE_SIZE) {
|
||||
int excess;
|
||||
int nchar;
|
||||
|
||||
excess = size - (pvtData.buffersize -(message - pbuffer));
|
||||
message[TRUNCATE_SIZE] = 0;
|
||||
if(excess> 0) {
|
||||
printf("errlog: A message overran buffer by %d. This is VERY bad\n",
|
||||
excess);
|
||||
nchar = sprintf(&message[TRUNCATE_SIZE],
|
||||
"\nerrlog = previous message overran buffer. It was truncated."
|
||||
" size = %d excess = %d\n", size,excess);
|
||||
} else {
|
||||
nchar = sprintf(&message[TRUNCATE_SIZE],
|
||||
"\nerrlog = previous message too long. It was truncated."
|
||||
" size=%d It was truncated\n",size);
|
||||
}
|
||||
pnextSend->length = TRUNCATE_SIZE + nchar +1;
|
||||
} else {
|
||||
pnextSend->length = size+1;
|
||||
}
|
||||
ellAdd(&pvtData.msgQueue,&pnextSend->node);
|
||||
semGive(pvtData.msgQueueLock);
|
||||
semGive(pvtData.errlogTaskWaitForWork);
|
||||
}
|
||||
|
||||
/*errlogTask is the only task that calls msgbufGetSend and msgbufFreeSend*/
|
||||
/*Thus errlogTask is the ONLY task that removes messages from msgQueue */
|
||||
/*This is why each can lock and unlock msgQueue */
|
||||
/*This is necessary to prevent other tasks from waiting for errlogTask */
|
||||
LOCAL char * msgbufGetSend()
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
pvtSemTake(pvtData.msgQueueLock);
|
||||
pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue);
|
||||
semGive(pvtData.msgQueueLock);
|
||||
if(!pnextSend) return(0);
|
||||
return(pnextSend->message);
|
||||
}
|
||||
|
||||
LOCAL void msgbufFreeSend()
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
pvtSemTake(pvtData.msgQueueLock);
|
||||
pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue);
|
||||
if(!pnextSend) {
|
||||
printf("errlog: msgbufFreeSend logic error\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
ellDelete(&pvtData.msgQueue,&pnextSend->node);
|
||||
semGive(pvtData.msgQueueLock);
|
||||
}
|
||||
|
||||
LOCAL void *pvtCalloc(size_t count,size_t size)
|
||||
{
|
||||
size_t *pmem;
|
||||
|
||||
pmem = calloc(count,size);
|
||||
if(!pmem) {
|
||||
printf("calloc failed in errlog\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
return(pmem);
|
||||
}
|
||||
|
||||
LOCAL void pvtSemTake(SEM_ID semid)
|
||||
{
|
||||
if(semTake(semid,WAIT_FOREVER)!=OK) {
|
||||
logMsg("epicsPrint: semTake returned error\n",0,0,0,0,0,0);
|
||||
taskSuspend(0);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,9 @@
|
||||
/*epicsPrint.h */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#define epicsPrintUseProtoANSI
|
||||
#endif
|
||||
/*This is now obsolete. Remlaced by errlog.h */
|
||||
#ifndef INCepicsPrintH
|
||||
#define INCepicsPrintH
|
||||
|
||||
#ifdef __STDC__
|
||||
#ifndef epicsPrintUseProtoANSI
|
||||
#define epicsPrintUseProtoANSI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef vxWorks
|
||||
# ifdef epicsPrintUseProtoANSI
|
||||
# include <stdarg.h>
|
||||
int epicsPrintf(const char *pFormat, ...);
|
||||
int epicsVprintf (const char *pFormat, va_list pvar);
|
||||
int iocLogVPrintf(const char *pFormat, va_list pvar);
|
||||
int iocLogPrintf(const char *pFormat, ...);
|
||||
# else /* not epicsPrintUseProtoANSI */
|
||||
int epicsPrintf();
|
||||
int epicsVprintf ();
|
||||
int iocLogVPrintf();
|
||||
int iocLogPrintf();
|
||||
# endif /* ifdef epicsPrintUseProtoANSI */
|
||||
#else /* not vxWorks */
|
||||
# define epicsPrintf printf
|
||||
# define epicsVprintf vprintf
|
||||
#endif /* ifdef vxWorks */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#include "errlog.h"
|
||||
|
||||
#endif /*INCepicsPrintH*/
|
||||
|
||||
@@ -61,6 +61,10 @@ extern "C" {
|
||||
#include "ellLib.h"
|
||||
#include "shareLib.h"
|
||||
|
||||
/*The following is only included because before 3.13.0beta12 errMessage */
|
||||
/*and errPrintf were defined here */
|
||||
#include "errlog.h"
|
||||
|
||||
#define RTN_SUCCESS(STATUS) ((STATUS)==0)
|
||||
|
||||
#define M_dbAccess (501 <<16) /*Database Access Routines */
|
||||
@@ -88,13 +92,6 @@ extern "C" {
|
||||
#define M_bucket (525 <<16) /*Bucket Hash*/
|
||||
#define M_gddFuncTbl (526 <<16) /*gdd jump table*/
|
||||
|
||||
/*
|
||||
* redefine errMessage with a macro so we can print
|
||||
* the file and line number
|
||||
*/
|
||||
#define errMessage(S, PM) \
|
||||
errPrintf(S, __FILE__, __LINE__, PM)
|
||||
|
||||
#ifdef errMDefUseProtoANSI
|
||||
epicsShareFunc int epicsShareAPI errSymFind(long status, char *name);
|
||||
epicsShareFunc int epicsShareAPI UnixSymFind(long status, char *name, long *value);
|
||||
@@ -103,11 +100,8 @@ epicsShareFunc void epicsShareAPI errSymTest(unsigned short modnum, unsigned sho
|
||||
epicsShareFunc void epicsShareAPI errSymTestPrint(long errNum);
|
||||
epicsShareFunc int epicsShareAPI errSymBld();
|
||||
epicsShareFunc int epicsShareAPI errSymbolAdd (long errNum,char *name);
|
||||
epicsShareFunc void epicsShareAPI errPrintf(long status, const char *pFileName,
|
||||
int lineno, const char *pformat, ...);
|
||||
epicsShareFunc void epicsShareAPI errSymDump();
|
||||
epicsShareFunc void epicsShareAPI tstErrSymFind();
|
||||
epicsShareFunc void epicsShareAPI errInit(void);
|
||||
|
||||
#else /* errMDefUseProtoANSI */
|
||||
|
||||
@@ -118,7 +112,6 @@ epicsShareFunc int epicsShareAPI ModSymFind();
|
||||
epicsShareFunc void epicsShareAPI errSymTestPrint();
|
||||
epicsShareFunc int epicsShareAPI errSymBld();
|
||||
epicsShareFunc int epicsShareAPI errSymbolAdd();
|
||||
epicsShareFunc void epicsShareAPI errPrintf();
|
||||
epicsShareFunc void epicsShareAPI errSymDump();
|
||||
epicsShareFunc void epicsShareAPI tstErrSymFind();
|
||||
#endif /* errMDefUseProtoANSI */
|
||||
|
||||
479
src/libCom/error/errlog.c
Normal file
479
src/libCom/error/errlog.c
Normal file
@@ -0,0 +1,479 @@
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
/*
|
||||
* Author: Marty Kraimer and Jeff Hill
|
||||
* Date: 07JAN1998
|
||||
* NOTE: Original version is adaptation of old version of errPrintfVX.c
|
||||
*/
|
||||
|
||||
#include <vxWorks.h>
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <taskLib.h>
|
||||
#include <intLib.h>
|
||||
#include <semLib.h>
|
||||
#include <vxLib.h>
|
||||
#include <errnoLib.h>
|
||||
#include <logLib.h>
|
||||
|
||||
#include "epicsAssert.h"
|
||||
#define epicsExportSharedSymbols
|
||||
#define ERRLOG_INIT
|
||||
#include "errlog.h"
|
||||
#undef ERRLOG_INIT
|
||||
#undef epicsExportSharedSymbols
|
||||
#include "errMdef.h"
|
||||
#include "ellLib.h"
|
||||
#include "error.h"
|
||||
#include "task_params.h"
|
||||
|
||||
#ifndef LOCAL
|
||||
#define LOCAL static
|
||||
#endif /* LOCAL */
|
||||
|
||||
#define BUFFER_SIZE 1280
|
||||
#define MAX_MESSAGE_SIZE 256
|
||||
#define TRUNCATE_SIZE 80
|
||||
#define MAX_ALIGNMENT 8
|
||||
|
||||
LOCAL void errlogTask(void);
|
||||
|
||||
LOCAL char *msgbufGetFree(void);
|
||||
LOCAL void msgbufSetSize(int size);
|
||||
LOCAL char * msgbufGetSend(void);
|
||||
LOCAL void msgbufFreeSend(void);
|
||||
|
||||
LOCAL void *pvtCalloc(size_t count,size_t size);
|
||||
LOCAL void pvtSemTake(SEM_ID semid);
|
||||
|
||||
typedef struct listenerNode{
|
||||
ELLNODE node;
|
||||
errlogListener listener;
|
||||
}listenerNode;
|
||||
|
||||
/*each message consists of a msgNode immediately followed by the message */
|
||||
typedef struct msgNode {
|
||||
ELLNODE node;
|
||||
char *message;
|
||||
int length;
|
||||
} msgNode;
|
||||
|
||||
LOCAL struct {
|
||||
SEM_ID errlogTaskWaitForWork;
|
||||
SEM_ID msgQueueLock;
|
||||
SEM_ID listenerLock;
|
||||
ELLLIST listenerList;
|
||||
ELLLIST msgQueue;
|
||||
msgNode *pnextSend;
|
||||
int buffersize;
|
||||
int sevToLog;
|
||||
int toConsole;
|
||||
int missedMessages;
|
||||
void *pbuffer;
|
||||
}pvtData;
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogPrintf( const char *pFormat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
int nchar;
|
||||
|
||||
if(INT_CONTEXT()) {
|
||||
logMsg("errlogPrintf called from interrupt level\n",0,0,0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
va_start(pvar, pFormat);
|
||||
nchar = errlogVprintf(pFormat,pvar);
|
||||
va_end (pvar);
|
||||
return(nchar);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogVprintf(
|
||||
const char *pFormat,va_list pvar)
|
||||
{
|
||||
int nchar;
|
||||
char *pbuffer;
|
||||
|
||||
if(INT_CONTEXT()) {
|
||||
logMsg("errlogVprintf called from interrupt level\n",0,0,0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
pbuffer = msgbufGetFree();
|
||||
if(!pbuffer) return(0);
|
||||
nchar = vsprintf(pbuffer,pFormat,pvar);
|
||||
msgbufSetSize(nchar+1);/*include the \0*/
|
||||
return nchar;
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogMessage(const char *message)
|
||||
{
|
||||
int status;
|
||||
char *pbuffer;
|
||||
|
||||
if(INT_CONTEXT()) {
|
||||
status = logMsg ("errlogMessage called from interrupt level %s",
|
||||
message,0,0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
pbuffer = msgbufGetFree();
|
||||
if(!pbuffer) return(0);
|
||||
strcpy(pbuffer,message);
|
||||
msgbufSetSize(strlen(message) +1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogSevPrintf(
|
||||
const errlogSevEnum severity,const char *pFormat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
int nchar;
|
||||
|
||||
if(INT_CONTEXT()) {
|
||||
logMsg("errlogSevPrintf called from interrupt level\n",0,0,0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
if(pvtData.sevToLog>severity) return(0);
|
||||
va_start(pvar, pFormat);
|
||||
nchar = errlogSevVprintf(severity,pFormat,pvar);
|
||||
va_end (pvar);
|
||||
return(nchar);
|
||||
}
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogSevVprintf(
|
||||
const errlogSevEnum severity,const char *pFormat,va_list pvar)
|
||||
{
|
||||
char *pnext;
|
||||
int nchar;
|
||||
int totalChar=0;
|
||||
|
||||
if(pvtData.sevToLog>severity) return(0);
|
||||
if(INT_CONTEXT()) {
|
||||
logMsg("errlogSevVprintf called from interrupt level\n",0,0,0,0,0,0);
|
||||
return 0;
|
||||
}
|
||||
errlogInit(0);
|
||||
pnext = msgbufGetFree();
|
||||
if(!pnext) return(0);
|
||||
nchar = sprintf(pnext,"sevr=%s ",errlogGetSevEnumString(severity));
|
||||
pnext += nchar; totalChar += nchar;
|
||||
nchar = vsprintf(pnext,pFormat,pvar);
|
||||
pnext += nchar; totalChar += nchar;
|
||||
sprintf(pnext,"\n");
|
||||
totalChar += 2; /*include \n and \0*/
|
||||
msgbufSetSize(totalChar);
|
||||
return(nchar);
|
||||
}
|
||||
|
||||
epicsShareFunc char * epicsShareAPI errlogGetSevEnumString(
|
||||
const errlogSevEnum severity)
|
||||
{
|
||||
static char unknown[] = "unknown";
|
||||
|
||||
errlogInit(0);
|
||||
if(severity<0 || severity>3) return(unknown);
|
||||
return(errlogSevEnumString[severity]);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogSetSevToLog(
|
||||
const errlogSevEnum severity )
|
||||
{
|
||||
errlogInit(0);
|
||||
pvtData.sevToLog = severity;
|
||||
}
|
||||
|
||||
epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog()
|
||||
{
|
||||
errlogInit(0);
|
||||
return(pvtData.sevToLog);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogAddListener(
|
||||
errlogListener listener)
|
||||
{
|
||||
listenerNode *plistenerNode;
|
||||
|
||||
errlogInit(0);
|
||||
plistenerNode = pvtCalloc(1,sizeof(listenerNode));
|
||||
pvtSemTake(pvtData.listenerLock);
|
||||
plistenerNode->listener = listener;
|
||||
ellAdd(&pvtData.listenerList,&plistenerNode->node);
|
||||
semGive(pvtData.listenerLock);
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogRemoveListener(
|
||||
errlogListener listener)
|
||||
{
|
||||
listenerNode *plistenerNode;
|
||||
|
||||
errlogInit(0);
|
||||
pvtSemTake(pvtData.listenerLock);
|
||||
plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
|
||||
while(plistenerNode) {
|
||||
if(plistenerNode->listener==listener) {
|
||||
ellDelete(&pvtData.listenerList,&plistenerNode->node);
|
||||
free((void *)plistenerNode);
|
||||
break;
|
||||
}
|
||||
plistenerNode = (listenerNode *)ellNext(&plistenerNode->node);
|
||||
}
|
||||
semGive(pvtData.listenerLock);
|
||||
if(!plistenerNode) printf("errlogRemoveListener did not find listener\n");
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI eltc(int yesno)
|
||||
{
|
||||
errlogInit(0);
|
||||
pvtData.toConsole = yesno;
|
||||
}
|
||||
|
||||
epicsShareFunc void epicsShareAPI errPrintf(long status, const char *pFileName,
|
||||
int lineno, const char *pformat, ...)
|
||||
{
|
||||
va_list pvar;
|
||||
char *pnext;
|
||||
int nchar;
|
||||
int totalChar=0;
|
||||
|
||||
if(INT_CONTEXT()) {
|
||||
logMsg("errPrintf called from interrupt level\n",0,0,0,0,0,0);
|
||||
return;
|
||||
}
|
||||
errlogInit(0);
|
||||
pnext = msgbufGetFree();
|
||||
if(!pnext) return;
|
||||
if(pFileName){
|
||||
nchar = sprintf(pnext,"filename=\"%s\" line number=%d\n",
|
||||
pFileName, lineno);
|
||||
pnext += nchar; totalChar += nchar;
|
||||
}
|
||||
if(status==0) status = MYERRNO;
|
||||
if(status>0) {
|
||||
int rtnval;
|
||||
char name[256];
|
||||
|
||||
rtnval = errSymFind(status,name);
|
||||
if(rtnval) {
|
||||
unsigned short modnum,errnum;
|
||||
|
||||
modnum = status >> 16; errnum = status & 0xffff;
|
||||
nchar = sprintf(pnext, "status (%hu,%hu) not in symbol table ",
|
||||
modnum, errnum);
|
||||
} else {
|
||||
nchar = sprintf(pnext,"%s ",name);
|
||||
}
|
||||
pnext += nchar; totalChar += nchar;
|
||||
}
|
||||
va_start (pvar, pformat);
|
||||
nchar = vsprintf(pnext,pformat,pvar);
|
||||
va_end (pvar);
|
||||
if(nchar>0) {
|
||||
pnext += nchar;
|
||||
totalChar += nchar;
|
||||
}
|
||||
sprintf(pnext,"\n");
|
||||
totalChar += 2; /*include the \n and the \0*/
|
||||
msgbufSetSize(totalChar);
|
||||
}
|
||||
|
||||
#define optionsSemM SEM_Q_PRIORITY|SEM_DELETE_SAFE|SEM_INVERSION_SAFE
|
||||
epicsShareFunc void epicsShareAPI errlogInit(int bufsize)
|
||||
{
|
||||
static int errlogInitFlag=0;
|
||||
void *pbuffer;;
|
||||
|
||||
if(!vxTas(&errlogInitFlag)) return;
|
||||
if(bufsize<BUFFER_SIZE) bufsize = BUFFER_SIZE;
|
||||
pvtData.buffersize = bufsize;
|
||||
ellInit(&pvtData.listenerList);
|
||||
ellInit(&pvtData.msgQueue);
|
||||
pvtData.toConsole = TRUE;
|
||||
if((pvtData.errlogTaskWaitForWork=semBCreate(SEM_Q_FIFO,SEM_EMPTY))==NULL) {
|
||||
logMsg("semBCreate failed in errlogInit",0,0,0,0,0,0);
|
||||
taskSuspend(0);
|
||||
}
|
||||
if((pvtData.listenerLock=semMCreate(optionsSemM))==NULL) {
|
||||
logMsg("semMCreate failed in errlogInit",0,0,0,0,0,0);
|
||||
taskSuspend(0);
|
||||
}
|
||||
if((pvtData.msgQueueLock=semMCreate(optionsSemM))==NULL) {
|
||||
logMsg("semMCreate failed in errlogInit",0,0,0,0,0,0);
|
||||
taskSuspend(0);
|
||||
}
|
||||
/*Allow an extra MAX_MESSAGE_SIZE for extra margain of safety*/
|
||||
pbuffer = pvtCalloc(pvtData.buffersize+MAX_MESSAGE_SIZE,sizeof(char));
|
||||
pvtData.pbuffer = pbuffer;
|
||||
taskSpawn(ERRLOG_NAME,ERRLOG_PRI,ERRLOG_OPT,
|
||||
ERRLOG_STACK,(FUNCPTR)errlogTask,
|
||||
0,0,0,0,0,0,0,0,0,0);
|
||||
}
|
||||
|
||||
LOCAL void errlogTask(void)
|
||||
{
|
||||
listenerNode *plistenerNode;
|
||||
|
||||
while(TRUE) {
|
||||
char *pmessage;
|
||||
|
||||
pvtSemTake(pvtData.errlogTaskWaitForWork);
|
||||
while((pmessage = msgbufGetSend())) {
|
||||
pvtSemTake(pvtData.listenerLock);
|
||||
if(pvtData.toConsole) printf("%s",pmessage);
|
||||
plistenerNode = (listenerNode *)ellFirst(&pvtData.listenerList);
|
||||
while(plistenerNode) {
|
||||
(*plistenerNode->listener)(pmessage);
|
||||
plistenerNode = (listenerNode *)ellNext(&plistenerNode->node);
|
||||
}
|
||||
semGive(pvtData.listenerLock);
|
||||
msgbufFreeSend();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LOCAL msgNode *msgbufGetNode()
|
||||
{
|
||||
char *pbuffer = (char *)pvtData.pbuffer;
|
||||
msgNode *pnextSend = 0;
|
||||
|
||||
if(ellCount(&pvtData.msgQueue) == 0 ) {
|
||||
pnextSend = (msgNode *)pbuffer;
|
||||
} else {
|
||||
int needed;
|
||||
int remaining;
|
||||
msgNode *plast;
|
||||
|
||||
plast = (msgNode *)ellLast(&pvtData.msgQueue);
|
||||
needed = MAX_MESSAGE_SIZE + sizeof(msgNode) + MAX_ALIGNMENT;
|
||||
remaining = pvtData.buffersize
|
||||
- ((plast->message - pbuffer) + plast->length);
|
||||
if(needed < remaining) {
|
||||
int length,adjust;
|
||||
|
||||
length = plast->length;
|
||||
/*Make length a multiple of MAX_ALIGNMENT*/
|
||||
adjust = length%MAX_ALIGNMENT;
|
||||
if(adjust) length += (MAX_ALIGNMENT-adjust);
|
||||
pnextSend = (msgNode *)(plast->message + length);
|
||||
}
|
||||
}
|
||||
if(!pnextSend) return(0);
|
||||
pnextSend->message = (char *)pnextSend + sizeof(msgNode);
|
||||
pnextSend->length = 0;
|
||||
return(pnextSend);
|
||||
}
|
||||
|
||||
LOCAL char *msgbufGetFree()
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
pvtSemTake(pvtData.msgQueueLock);
|
||||
if((ellCount(&pvtData.msgQueue) == 0) && pvtData.missedMessages) {
|
||||
int nchar;
|
||||
|
||||
pnextSend = msgbufGetNode();
|
||||
nchar = sprintf(pnextSend->message,"errlog = %d messages were discarded\n",
|
||||
pvtData.missedMessages);
|
||||
pnextSend->length = nchar + 1;
|
||||
pvtData.missedMessages = 0;
|
||||
ellAdd(&pvtData.msgQueue,&pnextSend->node);
|
||||
}
|
||||
pvtData.pnextSend = pnextSend = msgbufGetNode();
|
||||
if(pnextSend) return(pnextSend->message);
|
||||
++pvtData.missedMessages;
|
||||
semGive(pvtData.msgQueueLock);
|
||||
return(0);
|
||||
}
|
||||
|
||||
LOCAL void msgbufSetSize(int size)
|
||||
{
|
||||
char *pbuffer = (char *)pvtData.pbuffer;
|
||||
msgNode *pnextSend = pvtData.pnextSend;
|
||||
char *message = pnextSend->message;
|
||||
|
||||
if(size>MAX_MESSAGE_SIZE) {
|
||||
int excess;
|
||||
int nchar;
|
||||
|
||||
excess = size - (pvtData.buffersize -(message - pbuffer));
|
||||
message[TRUNCATE_SIZE] = 0;
|
||||
if(excess> 0) {
|
||||
printf("errlog: A message overran buffer by %d. This is VERY bad\n",
|
||||
excess);
|
||||
nchar = sprintf(&message[TRUNCATE_SIZE],
|
||||
"\nerrlog = previous message overran buffer. It was truncated."
|
||||
" size = %d excess = %d\n", size,excess);
|
||||
} else {
|
||||
nchar = sprintf(&message[TRUNCATE_SIZE],
|
||||
"\nerrlog = previous message too long. It was truncated."
|
||||
" size=%d It was truncated\n",size);
|
||||
}
|
||||
pnextSend->length = TRUNCATE_SIZE + nchar +1;
|
||||
} else {
|
||||
pnextSend->length = size+1;
|
||||
}
|
||||
ellAdd(&pvtData.msgQueue,&pnextSend->node);
|
||||
semGive(pvtData.msgQueueLock);
|
||||
semGive(pvtData.errlogTaskWaitForWork);
|
||||
}
|
||||
|
||||
/*errlogTask is the only task that calls msgbufGetSend and msgbufFreeSend*/
|
||||
/*Thus errlogTask is the ONLY task that removes messages from msgQueue */
|
||||
/*This is why each can lock and unlock msgQueue */
|
||||
/*This is necessary to prevent other tasks from waiting for errlogTask */
|
||||
LOCAL char * msgbufGetSend()
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
pvtSemTake(pvtData.msgQueueLock);
|
||||
pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue);
|
||||
semGive(pvtData.msgQueueLock);
|
||||
if(!pnextSend) return(0);
|
||||
return(pnextSend->message);
|
||||
}
|
||||
|
||||
LOCAL void msgbufFreeSend()
|
||||
{
|
||||
msgNode *pnextSend;
|
||||
|
||||
pvtSemTake(pvtData.msgQueueLock);
|
||||
pnextSend = (msgNode *)ellFirst(&pvtData.msgQueue);
|
||||
if(!pnextSend) {
|
||||
printf("errlog: msgbufFreeSend logic error\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
ellDelete(&pvtData.msgQueue,&pnextSend->node);
|
||||
semGive(pvtData.msgQueueLock);
|
||||
}
|
||||
|
||||
LOCAL void *pvtCalloc(size_t count,size_t size)
|
||||
{
|
||||
size_t *pmem;
|
||||
|
||||
pmem = calloc(count,size);
|
||||
if(!pmem) {
|
||||
printf("calloc failed in errlog\n");
|
||||
taskSuspend(0);
|
||||
}
|
||||
return(pmem);
|
||||
}
|
||||
|
||||
LOCAL void pvtSemTake(SEM_ID semid)
|
||||
{
|
||||
if(semTake(semid,WAIT_FOREVER)!=OK) {
|
||||
logMsg("epicsPrint: semTake returned error\n",0,0,0,0,0,0);
|
||||
taskSuspend(0);
|
||||
}
|
||||
}
|
||||
95
src/libCom/error/errlog.h
Normal file
95
src/libCom/error/errlog.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* src/libCom/errlog.h */
|
||||
/*****************************************************************
|
||||
COPYRIGHT NOTIFICATION
|
||||
*****************************************************************
|
||||
|
||||
(C) COPYRIGHT 1993 UNIVERSITY OF CHICAGO
|
||||
|
||||
This software was developed under a United States Government license
|
||||
described on the COPYRIGHT_UniversityOfChicago file included as part
|
||||
of this distribution.
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef INCerrlogh
|
||||
#define INCerrlogh
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#define epicsPrintUseProtoANSI
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
#ifndef epicsPrintUseProtoANSI
|
||||
#define epicsPrintUseProtoANSI
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* define errMessage with a macro so we can print the file and line number*/
|
||||
#define errMessage(S, PM) \
|
||||
errPrintf(S, __FILE__, __LINE__, PM)
|
||||
/* epicsPrintf and epicsVprintf old versions of errlog routines*/
|
||||
#define epicsPrintf errlogPrintf
|
||||
#define epicsVprintf errlogVprintf
|
||||
|
||||
typedef void(*errlogListener) (const char *message);
|
||||
typedef enum {errlogInfo,errlogMinor,errlogMajor,errlogFatal} errlogSevEnum;
|
||||
extern char * errlogSevEnumString[];
|
||||
#ifdef ERRLOG_INIT
|
||||
char * errlogSevEnumString[] = {"info","minor","major","fatal"};
|
||||
#endif
|
||||
|
||||
#ifdef epicsPrintUseProtoANSI
|
||||
|
||||
epicsShareFunc int epicsShareAPI errlogPrintf(
|
||||
const char *pformat, ...);
|
||||
epicsShareFunc int epicsShareAPI errlogVprintf(
|
||||
const char *pformat,va_list pvar);
|
||||
epicsShareFunc int epicsShareAPI errlogSevPrintf(
|
||||
const errlogSevEnum severity,const char *pformat, ...);
|
||||
epicsShareFunc int epicsShareAPI errlogSevVprintf(
|
||||
const errlogSevEnum severity,const char *pformat,va_list pvar);
|
||||
epicsShareFunc int epicsShareAPI errlogMessage(
|
||||
const char *message);
|
||||
|
||||
epicsShareFunc char * epicsShareAPI errlogGetSevEnumString(
|
||||
const errlogSevEnum severity);
|
||||
epicsShareFunc void epicsShareAPI errlogSetSevToLog(
|
||||
const errlogSevEnum severity );
|
||||
epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog(void);
|
||||
|
||||
epicsShareFunc void epicsShareAPI errlogAddListener(
|
||||
errlogListener listener);
|
||||
epicsShareFunc void epicsShareAPI errlogRemoveListener(
|
||||
errlogListener listener);
|
||||
|
||||
epicsShareFunc void epicsShareAPI eltc(int yesno);
|
||||
epicsShareFunc void epicsShareAPI errlogInit(int bufsize);
|
||||
|
||||
/*other routines that write to log file*/
|
||||
epicsShareFunc void epicsShareAPI errPrintf(long status, const char *pFileName,
|
||||
int lineno, const char *pformat, ...);
|
||||
|
||||
#else /* not epicsPrintUseProtoANSI */
|
||||
epicsShareFunc int epicsShareAPI errlogPrintf();
|
||||
epicsShareFunc int epicsShareAPI errlogVprintf();
|
||||
epicsShareFunc int epicsShareAPI errlogSevPrintf();
|
||||
epicsShareFunc int epicsShareAPI errlogSevVprintf();
|
||||
epicsShareFunc int epicsShareAPI errlogMessage();
|
||||
epicsShareFunc char * epicsShareAPI errlogGetSevEnumString();
|
||||
epicsShareFunc void epicsShareAPI errlogSetSevToLog();
|
||||
epicsShareFunc errlogSevEnum epicsShareAPI errlogGetSevToLog();
|
||||
epicsShareFunc void epicsShareAPI errlogAddListener();
|
||||
epicsShareFunc void epicsShareAPI errlogRemoveListener();
|
||||
epicsShareFunc void epicsShareAPI eltc();
|
||||
epicsShareFunc void epicsShareAPI errlogInit();
|
||||
epicsShareFunc void epicsShareAPI errPrintf();
|
||||
#endif /* ifdef epicsPrintUseProtoANSI */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*INCerrlogh*/
|
||||
Reference in New Issue
Block a user