AcePerl

 view release on metacpan or  search on metacpan

acelib/messubs.c  view on Meta::CPAN

/*  File: messubs.c
 *  Author: Richard Durbin (rd@mrc-lmb.cam.ac.uk)
 *  Copyright (C) J Thierry-Mieg and R Durbin, 1992
 *-------------------------------------------------------------------
 * This file is part of the ACEDB genome database package, written by
 * 	Richard Durbin (MRC LMB, UK) rd@mrc-lmb.cam.ac.uk, and
 *	Jean Thierry-Mieg (CRBM du CNRS, France) mieg@kaa.cnrs-mop.fr
 *
 * Description: low level: encapsulates vararg messages, *printf,
 *			crash handler,
 *
 * Exported functions: see regular.h
 *
 * HISTORY:
 * Last edited: Nov 27 15:36 1998 (fw)
 * * Nov 19 13:26 1998 (edgrif): Removed the test for errorCount and messQuery
 *              in messerror, really the wrong place.
 * * Oct 22 15:26 1998 (edgrif): Replaced strdup's with strnew.
 * * Oct 21 15:07 1998 (edgrif): Removed messErrorCount stuff from graphcon.c
 *              and added to messerror (still not perfect), this was a new.
 *              bug in the message system.
 * * Sep 24 16:47 1998 (edgrif): Remove references to ACEDB in messages,
 *              change messExit prefix to "EXIT: "
 * * Sep 22 14:35 1998 (edgrif): Correct errors in buffer usage by message
 *              outputting routines and message formatting routines.
 * * Sep 11 09:22 1998 (edgrif): Add messExit routine.
 * * Sep  9 16:52 1998 (edgrif): Add a messErrorInit function to allow an
 *              application to register its name for use in crash messages.
 * * Sep  3 11:32 1998 (edgrif): Rationalise strings used as prefixes for
 *              messages. Add support for new messcrash macro to replace
 *              messcrash routine, this includes file/line info. for
 *              debugging (see regular.h for macro def.) and a new
 *              uMessCrash routine.
 * * Aug 25 14:51 1998 (edgrif): Made BUFSIZE enum (shows up in debugger).
 *              Rationalise the use of va_xx calls into a single macro/
 *              function and improve error checking on vsprintf.
 *              messdump was writing into messbuf half way up, I've stopped
 *              this and made two buffers of half the original size, one for
 *              messages and one for messdump.
 * * Aug 21 13:43 1998 (rd): major changes to make clean from NON_GRAPHICS
 *              and ACEDB.  Callbacks can be registered for essentially
 *              all functions.  mess*() versions continue to centralise
 *              handling of ... via stdarg.
 * * Aug 20 17:10 1998 (rd): moved memory handling to memsubs.c
 * * Jul  9 11:54 1998 (edgrif): 
 *              Fixed problem with SunOS not having strerror function, system
 *              is too old to have standard C libraries, have reverted to
 *              referencing sys_errlist for SunOS only.
 *              Also fixed problem with getpwuid in getLogin function, code
 *              did not check return value from getpwuid function.
 * * Jul  7 10:36 1998 (edgrif):
 *      -       Replaced reference to sys_errlist with strerror function.
 * * DON'T KNOW WHO MADE THESE CHANGES...NO RECORD IN HEADER....(edgrif)
 *      -       newformat added for the log file on mess dump.
 *      -       Time, host and pid are now always the first things written.
 *      -       This is for easier checking og the log.wrm with scripts etc.
 *      -       Messquery added for > 50 minor errors to ask if user wants to crash.
 *      -       Made user,pid and host static in messdump.
 * * Dec  3 15:52 1997 (rd)
 * 	-	messout(): defined(_WINDOW) =>!defined(NON_GRAPHIC)
 * * Dec 16 17:26 1996 (srk)
 * * Aug 15 13:29 1996 (srk)
 *	-	WIN32 and MACINTOSH: seteuid() etc. are stub functions
 * * Jun 6 10:50 1996 (rbrusk): compile error fixes
 * * Jun  4 23:31 1996 (rd)
 * Created: Mon Jun 29 14:15:56 1992 (rd)
 *-------------------------------------------------------------------
 */

/* $Id: messubs.c,v 1.1 2002/11/14 20:00:06 lstein Exp $ */

#include <assert.h>
#include <errno.h>
#include "regular.h"
#include "freeout.h"				  /* messbeep uses freeOutF */



/* This is horrible...a hack for sunos which is not standard C compliant.    */
/* to allow accessing system library error messages, will disappear....      */
#ifdef SUN
extern const char *sys_errlist[] ;
#endif


/* Mac has its own routine for crashing, see messcrash for usage.            */
#if !defined(MACINTOSH) 
extern void crashOut (char* text) ;
#endif



/* This buffer is used only by the routines that OUTPUT a message. Routines  */
/* that format messages into buffers (e.g. messprintf, messSysErrorText)     */
/* have their own buffers. Note that there is a problem here in that this    */
/* buffer can be overflowed, unfortunately because we use vsprintf to do     */
/* our formatting, this can only be detected after the event.                */
/*                                                                           */
/* Constraints on message buffer size - applicable to ALL routines that      */
/* format externally supplied strings.                                       */

acelib/messubs.c  view on Meta::CPAN

  va_list args ;

  /* Format the message string.                                              */
  ACEFORMATSTRING(args, format, mesg_buf, NULL, &dumpbuf[0], BUFSIZE)

  strcat (mesg_buf, "\n") ;			  /* assume we are writing to a file */

  if (dumpRoutine)
    (*dumpRoutine)(mesg_buf) ;
}


/*****************************************/


/* Access function for returning running error total.                        */
UTIL_FUNC_DEF int messErrorCount (void) { return errorCount_G ; }


/* Output a non-fatal error message, for all messages a call to messdump is  */
/* made which may result in the message being logged. The single error count */
/* is also incremented so that functions can use this to check how many      */
/* errors have been recorded so far.                                         */
UTIL_FUNC_DEF void messerror (char *format, ...)
{
  char *prefix = ERROR_PREFIX ;
  char *mesg_buf = NULL ;
  va_list args ;

  /* always increment the error count.                                       */
  ++errorCount_G ;

  /* Format the message string.                                              */
  ACEFORMATSTRING(args, format, mesg_buf, prefix, NULL, 0) ;

  /* If application registered an error handler routine, call it.            */
  if (errorJmpBuf)
    longjmp (*errorJmpBuf, 1) ;

  /* Log the message.                                                        */
  messdump(mesg_buf) ;

  /* Now report the error to the user.                                       */
  if (errorRoutine)
    (*errorRoutine)(mesg_buf) ;
  else
    fprintf (stderr, "%s\n", mesg_buf) ;

  invokeDebugger () ;
}



/*******************************/

/* Use this function for errors that while being unrecoverable are not a     */
/* problem with the acedb code, e.g. if the user starts xace without         */
/* specifying a database.                                                    */
/* Note that there errors are logged but that this routine will exit without */
/* any chance to interrupt it (e.g. the crash routine in uMessCrash), this   */
/* could be changed to allow the application to register an exit handler.    */
/*                                                                           */
UTIL_FUNC_DEF void messExit(char *format, ...)
  {
  char *prefix = EXIT_PREFIX ;
  char *mesg_buf = NULL ;
  va_list args ;

  /* Format the message string.                                              */
  ACEFORMATSTRING(args, format, mesg_buf, prefix, NULL, 0) ;

  if (exitRoutine)
    (*exitRoutine)(mesg_buf) ;
  else
    fprintf (stderr, "%s\n", mesg_buf) ;

#if defined(MACINTOSH)
  crashOut(mesg_buf) ;
#else
  messdump(mesg_buf) ;

  exit(EXIT_FAILURE) ;
#endif

  return ;					  /* Should never get here. */
  }


/*******************************/

/* This is the routine called by the messcrash macro (see regular.h) which   */
/* actually does the message/handling and exit.                              */
/* This routine may encounter errors itself, in which case it will attempt   */
/* to call itself to report the error. To avoid infinite recursion we limit  */
/* this to just one reporting of an internal error and then we abort.        */
/*                                                                           */
UTIL_FUNC_DEF void uMessCrash(char *format, ...)
  {
  enum {MAXERRORS = 1} ;
  static int internalErrors = 0 ;
  static char prefix[1024] ;
  int rc ;
  char *mesg_buf = NULL ;
  va_list args ;

  /* Check for recursive calls and abort if necessary.                       */
  if (internalErrors > MAXERRORS) 
    {
      fprintf (stderr, "%s : fatal internal error, abort", 
	       messageG.progname);
      abort() ;
    }
  else internalErrors++ ;

  /* Construct the message prefix, adding the program name if possible.      */
  if (messGetErrorProgram() == NULL)
       rc = sprintf(prefix, CRASH_PREFIX_FORMAT, messGetErrorFile(), messGetErrorLine()) ;
  else
       rc = sprintf(prefix, FULL_CRASH_PREFIX_FORMAT,
		    messGetErrorProgram(), messGetErrorFile(), messGetErrorLine()) ;
  if (rc < 0) messcrash("sprintf failed") ;



( run in 1.083 second using v1.01-cache-2.11-cpan-5a3173703d6 )