// ////////////////////////////////////////////////////////////////////////////
//
//  File:      TFError.cpp
//
//  Version:   1.0
//
//  Author:    Reiner Rohlfs (GADC)
//
//  History:   1.0   11.07.03  first released version
//
// ////////////////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <stdarg.h>

#include "Rtypes.h"

#include "TFError.h"

ClassImp(TFError)
ClassImp(TFErrMsg)
ClassImp(TFException)

//_____________________________________________________________________________
// TFError:
//    The TFError class has only static member function and can store several
//    error messages. The oldest error message will be deleted as soon as the 
//    maximum number of error message is reached. But the number of stored 
//    messages can be set ( see SetMaxErrors() - function ). The default value 
//    is 20 error messages.
//
//    Several of the TF - classes write error messages into this storage. At the
//    end of an application or at any time the error messages can be printed
//    with PrintErrors().
//
//
// TFErrMsg:
//    TFErrMsg is one error message used by the TFError class.
//    This class is not designed to be used by an application but only by
//    TFError
//
//
// TFException:
//    Some of the TF - methods throw an exception if for example
//    TFError::SetErrorType(kExceptionErr) was set. As default 
//    the functions do not throw an exception, but return an error status. 
//    The application program should catch them and can either print the 
//    error message with the PrintError() function or add the error message 
//    to the TFError class with the AddToError() function.
//

Int_t       TFError::fMaxErrors  = 20;
Int_t       TFError::fNumErrors  = 0;
TFErrMsg *  TFError::fErrMsgs    = NULL;
TFErrorType TFError::fErrorType  = kStoreErr;

//_____________________________________________________________________________
void TFErrMsg::Add(TFErrMsg * errMsg)
{
// Adds one error message to the linked list

   if (fNext)
      fNext->Add(errMsg);
   else
      fNext = errMsg;
}
//_____________________________________________________________________________
TFErrMsg * TFErrMsg::Remove()
{
// Removes and deletes this error message and returns the next message in 
// the linked list

   TFErrMsg * rc = fNext;
   fNext = NULL;
   delete this;
   return rc;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
void TFError::AddError(TString & function, TString & errorMsg)
{
// Adds one error message. The function name and a message should be 
// specified. The default length of the function name at the printout
// functions GetError() and PrintErrors(), is 24 characters.
// Independent of a previous call of SetErrorType() this function will 
// always store the error message and will never throw an 
// TFException - ecxeption.

   TFErrMsg * errMsg = new TFErrMsg;
   errMsg->fFunction = function;
   errMsg->fMsg = errorMsg;

   if (fErrMsgs)
      {
      fErrMsgs->Add(errMsg);
      if (fMaxErrors == fNumErrors)
         fErrMsgs = fErrMsgs->Remove();
      else
         fNumErrors++;
      }
   else
      {
      fErrMsgs = errMsg;
      fNumErrors = 1;
      }

}
//_____________________________________________________________________________
void TFError::SetError(const char * function, const char * errorMsg, ...)
{
// Set one error message. The function name and a message should be 
// specified. The default length of the function name at the printout
// functions GetError() and PrintErrors(), is 24 characters.
// The maximum length of the errorMsg is 1999 characters. 
// Depending on a previous call of SetErrorType() this function will store
// the error message, will throw an TFException - ecxeption or will do both.


   char hstr[2000];

   va_list vaList;
   va_start(vaList, errorMsg);
   vsprintf(hstr, errorMsg, vaList);
   va_end(vaList);

   if (fErrorType & kStoreErr)
      {
      TFErrMsg * errMsg = new TFErrMsg;
      errMsg->fFunction = function;
      errMsg->fMsg = hstr;

      if (fErrMsgs)
         {
         fErrMsgs->Add(errMsg);
         if (fMaxErrors == fNumErrors)
            fErrMsgs = fErrMsgs->Remove();
         else
            fNumErrors++;
         }
      else
         {
         fErrMsgs = errMsg;
         fNumErrors = 1;
         }
      }

   if (fErrorType & kExceptionErr)
      throw TFException(function, hstr);

}
//_____________________________________________________________________________
void TFError::RemveLastError()
{
// Removes the last, the youngest, error message from the list of messages

   TFErrMsg * prev = NULL; 
   TFErrMsg * errMsg = fErrMsgs;

   if (fErrMsgs == NULL)
      return;

   while (errMsg->fNext)
      {
      prev = errMsg;
      errMsg = errMsg->fNext;
      }
   
   delete errMsg;
   if (prev)
      prev->fNext = NULL;
   else
      fErrMsgs = NULL;
   fNumErrors--;

}
//_____________________________________________________________________________
void TFError::ClearErrors()
{
// Removes all error messages

   fNumErrors = 0; 
   delete fErrMsgs;
   fErrMsgs = NULL;
}
//_____________________________________________________________________________
void TFError::SetMaxErrors(Int_t num)
{
// Set the maximum number of stored error messages. The default value is 20
// The function will remove the oldest error messages if the number is set
// to be less than the actual stored error messages.

   if (num < 1)   num = 1;
   fMaxErrors = num;
   
   while (fNumErrors > fMaxErrors)
      {
      fErrMsgs = fErrMsgs->Remove();
      fNumErrors--;
      }
}
//_____________________________________________________________________________
void TFError::PrintErrors()
{
// Prints all error messages on standard output
// The oldest error is printed first

   TFErrMsg * errMsg = fErrMsgs;
   if (errMsg)
      printf("Error stack:\n");

   while (errMsg)
      {
      printf("%24s : %s\n", errMsg->fFunction.Data(), errMsg->fMsg.Data() );
      errMsg = errMsg->fNext;
      };
}
//_____________________________________________________________________________
char * TFError::GetError(int num, char * errStr)
{
// Gets one error message as string. The function and the error message
// is copied into the string errStr and the pointer errStr is returned.
// num defines the 0 based index of the message. The errStr will be empty
// if num >=  NumErrors(). The oldes error has num == 0.
// errStr has to be long enough to hold the function name and the error
// message. 2100 bytes should always be enough
   TFErrMsg * errMsg;

   errMsg = fErrMsgs;
   while (errMsg && num)
      {
      errMsg = errMsg->fNext;
      num--;
      }

   if (errMsg)
      sprintf(errStr, "%24s : %s", errMsg->fFunction.Data(), errMsg->fMsg.Data() );
   else
      errStr[0] = 0;

   return errStr;
}
//_____________________________________________________________________________
//_____________________________________________________________________________
TFException::TFException(const char * function, const char * errorMsg, ...)
{
// The function name and a message should be specified. The default length
// of the function name at the printout is 24 characters.
// The maximum length of the errorMsg is 1999 characters. 

   char hstr[2000];

   va_list vaList;
   va_start(vaList, errorMsg);
   vsprintf(hstr, errorMsg, vaList);
   va_end(vaList);

   fFunction = function;
   fMsg      = hstr;
}
//_____________________________________________________________________________
void TFException::PrintError()
{
// Prints the function name and the error messages on standard output

   printf("%24s : %s\n", fFunction.Data(), fMsg.Data() );
}


Last update: Fri Mar 14 13:55:15 2008

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.