summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgoodale <goodale@17b73243-c579-4c4c-a9d2-2d5706c11dac>2005-10-03 13:14:28 +0000
committergoodale <goodale@17b73243-c579-4c4c-a9d2-2d5706c11dac>2005-10-03 13:14:28 +0000
commitba4821ed7ee6aef53ec48d3739c77edad8bd7858 (patch)
treec80f8eddb21d902a486b3176a0b3a4f8c1ae27fd
parentde4ddf226c8b8f842d3ee40319fcc4f693899903 (diff)
Patch from Jian Tao to add some callback functionality to the
warning system. This allows thorns to register functions which will be called when CCTK_Warn or CCTK_Info are called, with the contents of the warning/info message, thus allowing thorns to do things like logging warnings to file or displaying on webpages. git-svn-id: http://svn.cactuscode.org/flesh/trunk@4157 17b73243-c579-4c4c-a9d2-2d5706c11dac
-rw-r--r--src/include/cctk_WarnLevel.h26
-rw-r--r--src/main/WarnLevel.c319
2 files changed, 342 insertions, 3 deletions
diff --git a/src/include/cctk_WarnLevel.h b/src/include/cctk_WarnLevel.h
index d867eae9..e826bfdf 100644
--- a/src/include/cctk_WarnLevel.h
+++ b/src/include/cctk_WarnLevel.h
@@ -47,11 +47,35 @@ __attribute__ ((format (printf, 2, 3)))
#endif
;
+/* prototypes for warn/info callback routines */
+
+typedef void (*cctk_warnfunc)(int level,
+ int line,
+ const char *file,
+ const char *thorn,
+ const char *message,
+ void *data);
+
+typedef void (*cctk_infofunc)(const char *thorn,
+ const char *message,
+ void *data);
+
+/* prototypes for warn/info registration routines */
+int CCTK_WarnCallbackRegister(int minlevel,
+ int maxlevel,
+ void *data,
+ cctk_warnfunc callback);
+
+
+int CCTK_InfoCallbackRegister(void *data,
+ cctk_infofunc callback);
+
+
#ifdef __cplusplus
}
#endif
-#endif /* CCODE */
+#endif /* CCODE */
/* suggested values for warning levels (courtesy of Steve, PR#1742) */
#define CCTK_WARN_ABORT 0 /* abort the Cactus run */
diff --git a/src/main/WarnLevel.c b/src/main/WarnLevel.c
index c3db295e..3d5872f9 100644
--- a/src/main/WarnLevel.c
+++ b/src/main/WarnLevel.c
@@ -66,11 +66,45 @@ void CCTK_FCALL CCTK_FNAME (CCTK_Warn)
THREE_FORTSTRING_ARG);
void CCTK_FCALL CCTK_FNAME (CCTK_ParamWarn)
(TWO_FORTSTRING_ARG);
-int CCTK_FCALL CCTK_FNAME (CCTK_MessageFormat)
+int CCTK_FCALL CCTK_FNAME (CCTK_MessageFormat)
(ONE_FORTSTRING_ARG);
void CCTK_FCALL CCTK_FNAME (CCTKi_NotYetImplemented)
(ONE_FORTSTRING_ARG);
+/********************************************************************
+ ******************** Internal Typedefs ************************
+ ********************************************************************/
+/* structure holding a callback function pointer together with other
+ * information to warn/info*/
+
+typedef struct warncallback
+{
+ struct warncallback *next;
+ cctk_warnfunc function;
+ void *data;
+ int minlevel;
+ int maxlevel;
+} t_warncallback;
+
+typedef struct infocallback
+{
+ struct infocallback *next;
+ cctk_infofunc function;
+ void *data;
+} t_infocallback;
+
+
+/********************************************************************
+ ******************** Internal Functions ************************
+ ********************************************************************/
+
+static void CCTKi_WarnCallbacksCall(int level,
+ int line,
+ const char *file,
+ const char *thorn,
+ const char *message);
+
+static void CCTKi_InfoCallbacksCall(const char *thorn, const char *message);
/********************************************************************
********************* Static Data *****************************
@@ -101,6 +135,10 @@ static int error_level = 0;
static int n_formats = 0;
static pKeyedData *formatlist = NULL;
+/* Store registered warn and info methods */
+static t_warncallback *warncallbacks = NULL;
+static t_infocallback *infocallbacks = NULL;
+
/*@@
@routine CCTK_Info
@@ -179,12 +217,45 @@ void CCTK_FCALL CCTK_FNAME (CCTK_Info)
int CCTK_VInfo (const char *thorn, const char *format, ...)
{
va_list ap;
-
+ int retval = -1;
static int info_format_decoded = 0; /* are the following two flags valid? */
/* Boolean flags decoded from cactus::info_format */
static int info_format_numeric = 0; /* print a numeric timestamp? */
static int info_format_human_readable = 0; /* print a human-readable timestamp? */
+/* necessary for wrapping up the final message */
+ int msg_size;
+ char *message = NULL;
+
+/* Start generating message only if the infocallback list is not NULL */
+ if(infocallbacks)
+ {
+ va_start(ap,format);
+
+/* one way to get the final string size */
+ msg_size = Util_vsnprintf(NULL, 0, format, ap);
+
+/* Empty string is ok */
+ if(msg_size >= 0)
+ {
+ message = (char *)malloc(msg_size+1);
+ }
+
+/* Try to print in the allocated space. */
+ if(message)
+ {
+ va_start(ap,format);
+ Util_vsnprintf(message,msg_size+1,format,ap);
+ va_end(ap);
+ }
+
+/* call the callback function */
+ CCTKi_InfoCallbacksCall(thorn,message);
+
+/* free the memory allocated for temp messsage */
+ free (message);
+ }
+
/*
* if we haven't already decoded cactus::info_format into the
* Boolean flags, do so
@@ -394,6 +465,39 @@ int CCTK_VWarn (int level,
int param_type;
int myproc;
va_list ap, aq;
+ int retval = -1;
+
+/* Necessary for wrapping up the final message */
+
+ int msg_size;
+ char *message = NULL;
+
+/* Start generating message only if the warbcallback list is not NULL */
+ if(warncallbacks)
+ {
+ va_start(ap,format);
+ msg_size = Util_vsnprintf(NULL, 0, format, ap);
+
+/* Empty string is ok */
+ if(msg_size >= 0)
+ {
+ message = (char *)malloc(msg_size+1);
+ }
+
+/* Try to print in the allocated space. */
+ if(message)
+ {
+ va_start(ap,format);
+ Util_vsnprintf(message,msg_size+1,format,ap);
+ va_end(ap);
+ }
+
+/* call the callback function */
+ CCTKi_WarnCallbacksCall(level,line,file,thorn,message);
+
+/* free the memory allocated for temp messsage */
+ free (message);
+ }
if (level <= warning_level || level <= logging_level)
{
@@ -659,6 +763,121 @@ int CCTK_VParamWarn (const char *thorn,
return (0);
}
+/*@@
+ @routine CCTK_WarnCallbackRegister
+ @date 05/17/2005
+ @author Jian Tao
+ @desc
+ Register warn callback function
+ @enddesc
+ @endvar
+ @var minlevel
+ @vdesc minimum warning level
+ @vtype int
+ @vio in
+ @endvar
+ @var maxlevel
+ @vdesc maximum warning level
+ @vtype int
+ @vio in
+ @endvar
+ @var data
+ @vdesc
+ @vtype int*
+ @vio in
+ @endvar
+ @var function
+ @vdesc Callback function (see cctk_WarnLevel.h)
+ @vtype cctk_warnfunc
+ @vio in
+ @endvar
+@@*/
+
+int CCTK_WarnCallbackRegister(int minlevel,
+ int maxlevel,
+ void *data,
+ cctk_warnfunc callback)
+
+{
+ int retval;
+ t_warncallback *newcallback;
+
+ newcallback = (t_warncallback *)malloc(sizeof(t_warncallback));
+
+/* Create a one way chain for all registered callbacks */
+ if(newcallback)
+ {
+ newcallback->next = warncallbacks;
+ warncallbacks = newcallback;
+ newcallback->function = callback;
+ newcallback->data = data;
+ newcallback->minlevel = minlevel;
+ newcallback->maxlevel = maxlevel;
+ retval = 0;
+ }
+ else
+ {
+ retval = -1;
+ }
+ return retval;
+}
+
+
+/*@@
+ @routine CCTK_InfoCallbackRegister
+ @date 05/17/2005
+ @author Jian Tao
+ @desc
+ Register info callback function
+ @enddesc
+ @endvar
+ @var minlevel
+ @vdesc minimum warning level
+ @vtype int
+ @vio in
+ @endvar
+ @var maxlevel
+ @vdesc maximum warning level
+ @vtype int
+ @vio in
+ @endvar
+ @var data
+ @vdesc
+ @vtype int*
+ @vio in
+ @endvar
+ @var function
+ @vdesc Callback function (see cctk_WarnLevel.h)
+ @vtype cctk_infofunc
+ @vio in
+ @endvar
+@@*/
+
+int CCTK_InfoCallbackRegister(void *data, cctk_infofunc callback)
+
+{
+ int retval;
+ t_infocallback *newcallback;
+
+ newcallback = (t_infocallback *)malloc(sizeof(t_infocallback));
+
+/* Create a one way chain for all registered callbacks */
+ if(newcallback)
+ {
+ newcallback->next = infocallbacks;
+ infocallbacks = newcallback;
+ newcallback->function = callback;
+ newcallback->data = data;
+ retval = 0;
+ }
+
+ else
+ {
+ retval = -1;
+ }
+ return retval;
+}
+
/*@@
@routine CCTK_MessageFormat
@@ -1043,4 +1262,100 @@ void CCTK_FCALL CCTK_FNAME (CCTK_VInfo)
}
}
+
#endif
+
+/*@@
+ @routine CCTKi_WarnCallbacksCall
+ @date 05/17/2005
+ @author Jian Tao
+ @desc
+ Call callback functions
+ @enddesc
+ @var level
+ @vdesc Warning level
+ @vtype int
+ @vio in
+ @endvar
+ @var line
+ @vdesc Line number of warning in originating file
+ @vtype int
+ @vio in
+ @endvar
+ @var file
+ @vdesc Name of originating file
+ @vtype const char *
+ @vio in
+ @endvar
+ @var thorn
+ @vdesc Name of originating thorn
+ @vtype const char *
+ @vio in
+ @endvar
+ @var message
+ @vdesc warning message to output to stderr
+ @vtype const char *
+ @vio in
+ @endvar
+@@*/
+
+static void CCTKi_WarnCallbacksCall(int level,
+ int line,
+ const char *file,
+ const char *thorn,
+ const char *message)
+{
+ t_warncallback *current;
+
+/*
+ * Go through all the registered call back functions
+ * static variable warncallbacks has already been checked to be not empty
+ */
+
+ for(current=warncallbacks; current; current=current->next)
+ {
+
+/* Check valid level */
+ if(level >= current->minlevel && level <= current->maxlevel)
+ {
+ current->function(level,line,file,thorn,message,current->data);
+ }
+
+ }
+ return;
+}
+
+/*@@
+ @routine CCTKi_InfoCallbacksCall
+ @date 05/17/2005
+ @author Jian Tao
+ @desc
+ Call callback functions
+ @enddesc
+ @var thorn
+ @vdesc Name of originating thorn
+ @vtype const char *
+ @vio in
+ @endvar
+ @var message
+ @vdesc warning message to output to stderr
+ @vtype const char *
+ @vio in
+ @endvar
+@@*/
+
+static void CCTKi_InfoCallbacksCall(const char *thorn, const char *message)
+{
+ t_infocallback *current;
+
+/*
+ * Go through all the registered call back functions
+ * static variable infocallbacks has already been checked to be not empty
+ */
+
+ for(current=infocallbacks; current; current=current->next)
+ {
+ current->function(thorn,message,current->data);
+ }
+ return;
+}