/* -------------------------------------------------------------------------
status.H - Status Messages for Handling Both Errors and Logs
-------------------------------------------------------------------------
Copyright (C) 2000-2001 Eric R. Schendel
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
------------------------------------------------------------------------- */
#ifndef LOGS_H
#define LOGS_H
#include <iostream>
#include <string>
/**
* Namespace for status messages such as for logging and errors. This
* namespace also keeps all the default definitions and helper functions
* dealing with the status message classes.
*
* @short Namespace for Status Messages such as Logs and Errors
* @see StatusMsgs#StatusMsg StatusMsgs#Log StatusMsgs#Error
*/
namespace StatusMsgs {
/**
* Enumeration for keeping track of a log's priority level.
* This enum has two functions:
*
* The first is selecting what types of logs are displayed. This is set by
* a @ref Log::Log constructor or the @ref Log::setLogLevel method.
*
* <pre>
* NONE: Will not display log messages.
* LOW : Will display all log messages expect NONE (LOW, MED, & HIGH).
* MED : Will display log messages with more detail (MED & HIGH).
* HIGH: Will display only the essential log messages (HIGH).
* </pre>
*
* The second is to assign a priority level to a log message. This is set by
* the @ref Log::operator() method.
*
* <pre>
* NONE: Log message will not be displayed (making it useless).
* LOW : Log message is of little value. It is more for tracing through
* the program internally (useful mostly for developers).
* MED : Log message represents more detail compared to HIGH level log
* messages such as pointing out some potential problems.
* HIGH: Log message is of great importance by pointing out major operations.
* </pre>
*
* @see StatusMsgs#Log
*/
enum LogLevel {NONE = 0, LOW = 1, MED = 2, HIGH = 3};
/**
* Enumeration for keeping track of an error's severity level.
*
* <pre>
* SUCCESS : No errors were recorded which is the default state.
* MINOR : Error is of something that can possible happen but is not desired.
* No error message is displayed and program execution continues on.
* MAJOR : Error is of something that is not suppose to happen but should not
* cripple the program. So the error message is displayed and program
* execution continues on.
* CRITICAL: Error is of something that should not happen at all and program
* execution will terminate immediately.
* </pre>
*
* @see StatusMsgs#Error
*/
enum ErrLevel {SUCCESS = 0, MINOR = 1, MAJOR = 2, CRITICAL = 3};
/**
* Default header size: [5]
*/
const short SM_HDRSZ = 5;
/**
* Default message body size: [38]
*/
const short SM_BODYSZ = 38;
/**
* Default divider between message body and header: [" "]
*/
const char SM_DIVIDER[] = " ";
/**
* Default message header border: ["|"]
*/
const char SM_BORDER[] = "|";
/**
* Default message header boarder for errors: ["="]
*/
const char SM_ERR_BORDER[] = "=";
/**
* Default message body: ["<Default Message>"]
*/
const char SM_DBODY[] = "<Default Message>";
/**
* Default header for status messages: ["MSG"]
*/
const char SM_MESSAGE[] = "MSG";
/**
* Default header for log messages: ["LOG"]
*/
const char SM_LOG[] = "LOG";
/**
* Default header for error messages: ["ERROR"]
*/
const char SM_ERROR[] = "ERROR";
/**
* Default left bracket used for message arguments: ["["]
*/
const char SM_LBRACK[] = "[";
/**
* Default right bracket used for message arguments: ["]"]
*/
const char SM_RBRACK[] = "]";
/**
* String to represent a NULL string: [""]
*/
const char SM_NULL[] = "";
/**
* This base class is responsible for storing, handling, and printing
* status messages which consists of a header and message body. This
* primarily helps in simplifying the task of displaying system messages to
* the user and/or developer.
*
* To make the output formating of all status messages work together, global
* variables were created to handle the message header and body sizes.
* Therefore when one of these change, it effects all status messages which use
* the StatusMsg base class.
*
* @short Base Class For Handling System Status Messages
* @see StatusMsgs#Log StatusMsgs#Error
*/
class StatusMsg {
public:
/**
* Sets default message of @ref SM_DBODY[]
*/
StatusMsg();
/**
* Copy constructor
*/
StatusMsg(const StatusMsg& msg);
/**
* Sets default message of @ref SM_DBODY[] along with specified string
* header and with border style, header size, and body size if needed.
*
* @param header Header of status message
* @param border Default header border: @ref SM_BORDER[]
* @param hsize Default header size for all objects: @ref SM_HDRSZ
* @param bsize Default body size for all objects: @ref SM_BODYSZ
*/
StatusMsg(const string& header, const string border = SM_BORDER,
const short hsize = head_size, const short bsize = body_size);
/**
* Set header of message along with boarder style if needed
*
* @param hd Header
* @param bdr Header border
*/
void setHeader(const string hd,
const string bdr = SM_BORDER) { hdr = hd; div = bdr; }
/**
* Set boarder style
*
* @param bdr Header border
*/
void setBoader(const string bdr) { div = bdr; }
/**
* Set body of message along with one string argument if needed
*
* @param bdy Status message
* @param ag Argument associated with message. Only able to handle
* one but might handle more in the future if needed. By
* default the argument is none.
*/
void setBody(const string bdy,
const string ag = SM_NULL) { body = bdy; arg = ag; }
/**
* Same as above but handles an unsigned character for the argument
*/
void setBody(const string bdy, const unsigned char& ag);
/**
* Same as above but handles an unsigned integer for the argument
*/
void setBody(const string bdy, const unsigned long ag);
/**
* Set header size for all StatusMsg objects. This method can be called
* either by an object or directly within the class by
* "StatusMsg::setHeaderSize(size)". If the actual string size of the
* header is less then this size, then spaces are appended to the
* header when displayed. And if the string size is greater than this
* size then the header is truncated when displayed.
*
* @param hsz Header Size. If 0, then a header is not displayed.
*/
static void setHeaderSize(const short hsz);
/**
* Set message body size for all StatusMsg object. This method can be
* called either by an object or directly within the class by
* "StatusMsg::setBodySize(size)". If the actual string size is less than
* this size and an arguement exists, then spaces are added in between
* when displayed. And if the string size is greater than this size
* then the message is truncated when displayed.
*
* @param msg Message Body Size
*/
static void setBodySize(const short msz) { body_size = msz; }
/**
* @return body of message
*/
string getBody() const { return body; }
/**
* @return argument of message
*/
string getArgument() const { return arg; }
/**
* Display status message with the appropriate formatting of the
* header and message body along with its argument if it exists. A
* default message would look something like:
*
* <pre>
* |header| Default Message [Argument]
* </pre>
*
* @param out ostream to output onto (default: cout)
*/
void printMsg(ostream& out = cout) const;
private:
static short head_size;
static short body_size;
string hdr;
string body;
string arg;
string div;
};
/**
* This class is a superset of @ref StatusMsg responsible for handling log
* messages. This class is very helpful in that it allows easy tracking of
* program execution where log messages can be assigned different levels of
* importance.
*
* see @ref LogLevel
*
* @short Class For Handling Log Messages
*/
class Log: public StatusMsg {
public:
/**
* Set log to default message and to display all log priority levels.
*
* @see StatusMsgs StatusMsgs#StatusMsg::StatusMsg
*/
Log(): StatusMsg() { out = &clog; setHeader(SM_LOG); lvl = LOW; }
/**
* Set log to default header mainly telling function or location of
* logging within the program.
*
* @param hdr Header
* @param level Default log level display setting: All except NONE
* @param ostr Default ostream to output onto: clog
*
* @see StatusMsgs StatusMsgs#StatusMsg::StatusMsg StatusMsgs#LogLevel
*/
Log(const string hdr, const LogLevel level = LOW, ostream& ostr = clog);
/**
* Parameter passing operator to return the log level for assignments
* requiring an enum LogLevel value. This is helpful in passing a
* LogLevel parameter as the object name, such as Log instead of
* Log.getLogLevel().
*
* see @ref LogLevel
*
* @return Current log level
*/
operator LogLevel() const { return getLogLevel(); }
/**
* This method allows for "log(LogLevel,message)" operations which
* first performs a check to make sure that the log's message priority
* level is acceptable related to the level specified by a @ref Log
* constructor. If it is, then the body message is set and printed.
*
* @param level Priority level of log message
* @param msg Main message of log
* @param arg Message argument of log (default: no argument)
* @param ostr ostream to output onto. If none specified, then the
* ostream set by the @ref Log constructor or @ref setOutput
* method is used. Note that clog ostream will not work as
* an option to this method.
*/
void operator()(const LogLevel& level, const string msg,
const string arg = SM_NULL, ostream& ostr = clog);
/**
* Same as above but handles an unsigned character for the argument
*/
void operator()(const LogLevel& level, const string msg,
const unsigned char& arg, ostream& ostr = clog);
/**
* Same as above but handles a character for the argument
*/
void operator()(const LogLevel& level, const string msg,
const char& arg, ostream& ostr = clog);
/**
* Same as above but handles an unsigned integer for the argument
*/
void operator()(const LogLevel& level, const string msg,
const unsigned int arg, ostream& ostr = clog);
/**
* Same as above but handles an integer for the argument
*/
void operator()(const LogLevel& level, const string msg,
const int arg, ostream& ostr = clog);
/**
* Same as above but handles an unsigned long for the argument
*/
void operator()(const LogLevel& level, const string msg,
const unsigned long arg, ostream& ostr = clog);
/**
* Same as above but handles a long for the argument
*/
void operator()(const LogLevel& level, const string msg,
const long arg, ostream& ostr = clog);
/**
* This overload operator is basically the same as the one above except
* this one is geared more towards lazy people who do not need to specify
* priority levels of log messages. The default LogLevel is HIGH, so when
* used in conjunction with the Log constructor with zero arguments, this
* method will print all logs.
*
* @param msg Main message of log
* @param arg Message argument of log (default: no argument)
* @param ostr ostream to output onto. If none specified, then the
* ostream set by the @ref Log constructor or @ref setOutput
* method is used. Note that clog ostream will not work as
* an option to this method.
*/
void operator()(const string msg, const long arg,
ostream& ostr = clog) { (*this)(HIGH, msg, arg, ostr); }
/**
* Same as above but handles an unsigned long for the argument
*/
void operator()(const string msg, const unsigned long arg,
ostream& ostr = clog) { (*this)(HIGH, msg, arg, ostr); }
/**
* Same as above but handles an integer for the argument
*/
void operator()(const string msg, const int arg,
ostream& ostr = clog) { (*this)(HIGH, msg, arg, ostr); }
/**
* Same as above but handles an unsigned integer for the argument
*/
void operator()(const string msg, const unsigned int arg,
ostream& ostr = clog) { (*this)(HIGH, msg, arg, ostr); }
/**
* Same as above but handles a character for the argument
*/
void operator()(const string msg, const char& arg,
ostream& ostr = clog) { (*this)(HIGH, msg, arg, ostr); }
/**
* Same as above but handles an unsigned character for the argument
*/
void operator()(const string msg, const unsigned char& arg,
ostream& ostr = clog) { (*this)(HIGH, msg, arg, ostr); }
/**
* Same as above but handles a character string for the argument
*/
void operator()(const string msg, const string arg = SM_NULL,
ostream& ostr = clog) { (*this)(HIGH, msg, arg, ostr); }
/**
* This method changes the default log level display setting which is
* originally set by a @ref Log constructor.
*
* see @ref LogLevel
*
* @param level Log level display setting
*/
void setLogLevel(const LogLevel level) { lvl = level; }
/**
* This method changes the current output ostream.
*
* @param newout New ostream for log's default output
*/
void setOutput(ostream& newout) { out = &newout; }
/**
* This method returns the log level display setting which is set by
* either the @ref Log constructor or @ref setLogLevel method.
*
* see @ref LogLevel
*
* @return Current log level
*/
LogLevel getLogLevel() const { return lvl; }
private:
ostream* out;
LogLevel lvl;
};
/**
* The Error class is a superset of @ref StatusMsg responsible for handling
* error messages which can have different levels of severity. This class gives
* an easy object oriented way of handling errors within a program and is found
* to be much easier to deal with compared to exceptions.
*
* Chances are all error messages within a program will want to be directed to
* one particular output and have the same header, therefore the Error ostream
* and error message header has been defined as global. This allows for the
* ability to easily redefine the location of error outputs for all Error
* objects with just one method call to @ref setOutput .
*
* see @ref StatusMsgs::ErrLevel
*
* @short Class For Handling Error Messages
*/
class Error: public StatusMsg {
public:
/**
* Set Error to default header. The header size is automatically assigned
* with the length of the hdr string, and by default creation this object
* is assigned the ErrLevel of SUCCESS which has an error number of 0.
*
* @param hdr Default header
* @param border Default header border
*
* @see StatusMsgs StatusMsgs#StatusMsg::StatusMsg
*/
Error(const string hdr = eheader, const string border = eboarder);
/** Copy constructor */
Error(const Error& err);
/**
* Copy assignment which has the special purpose of making sure that if
* an error exists in the original or new object, then the error with
* the greatest severity is maintained.
*/
Error& operator=(const Error& err);
/**
* Conversion operator to return error status for assignments requiring
* a boolean value. A way to understand this operator is for example
* "if(!err)" is "if no error then" and "if(err)" is "if error then".
*
* @return true if error and false otherwise
*/
operator bool() const { return (lvl != SUCCESS); }
/**
* Conversion operator to return the error number for assignments
* requiring an integer value. This is very useful in returning the error
* status of a program at termination.
*
* @return Error status number (Success = 0 or Error > 0)
*/
operator int() const { return num; }
/**
* Conversion operator to return the error level for assignments
* requiring an enum ErrLevel value. This is neccessary for doing compare
* expression with ErrLevel values, such as "if(err == MINOR) {...}".
*
* see @ref ErrLevel
*
* @return Error level
*/
operator ErrLevel() const { return lvl; }
/**
* This method allows for "err(ErrLevel,message)" operations to specify
* the error message along with an error level, or if a message
* argument is not available, it instead only updates the current error
* level along with actions. This method takes different actions
* depending on the ErrLevel passed to it:
*
* <pre>
* SUCCESS : Sets object to original successful state.
* MINOR : If msg argument exists, it sets the status message body.
* Then it sets or updates the error number to MINOR.
* MAJOR : If msg argument exists, it sets the status message body.
* Then it sets or updates the error number to MAJOR. Also
* it ends up printing the message body.
* CRITICAL: If msg argument exists, it sets the status message body.
* Then it prints the status message body along with the
* system error message as the argument. It then causes
* the program to exit immediately with the system error
* number.
* </pre>
*
* @param level Set or update priority level of error message
* @param msg Main message of error (default: previous message)
* @param arg Message argument of error (default: no argument)
* @param out ostream to output onto (default: global variable eout)
*/
void operator()(const ErrLevel& level, string msg = SM_DBODY,
string arg = SM_NULL, ostream& out = *eout);
/**
* Same as above but handles an unsigned character for the argument
*/
void operator()(const ErrLevel& level, const string msg,
const unsigned char& arg, ostream& out = *eout);
/**
* Same as above but handles a character for the argument
*/
void operator()(const ErrLevel& level, const string msg,
const char& arg, ostream& out = *eout);
/**
* Same as above but handles an unsigned integer for the argument
*/
void operator()(const ErrLevel& level, const string msg,
const unsigned int arg, ostream& out = *eout);
/**
* Same as above but handles an integer for the argument
*/
void operator()(const ErrLevel& level, const string msg,
const int arg, ostream& out = *eout);
/**
* Same as above but handles an unsigned long for the argument
*/
void operator()(const ErrLevel& level, const string msg,
const unsigned long arg, ostream& out = *eout);
/**
* Same as above but handles a long for the argument
*/
void operator()(const ErrLevel& level, const string msg,
const long arg, ostream& out = *eout);
/**
* This overload operator is basically the same as the one above, except
* this one is geared more towards lazy people who do not need to specify
* priority levels of error messages. The error level will default to
* MAJOR which is usually the most used error type.
*
* @param msg Main message of error
* @param arg Message argument of error (default: no argument)
* @param out ostream to output onto (default: global variable eout)
*/
void operator()(const string msg, const long arg,
ostream& out = *eout) { (*this)(MAJOR, msg, arg, out); }
/**
* Same as above but handles an unsigned long for the argument
*/
void operator()(const string msg, const unsigned long arg,
ostream& out = *eout) { (*this)(MAJOR, msg, arg, out); }
/**
* Same as above but handles an integer for the argument
*/
void operator()(const string msg, const int arg,
ostream& out = *eout) { (*this)(MAJOR, msg, arg, out); }
/**
* Same as above but handles an unsigned integer for the argument
*/
void operator()(const string msg, const unsigned int arg,
ostream& out = *eout) { (*this)(MAJOR, msg, arg, out); }
/**
* Same as above but handles a character for the argument
*/
void operator()(const string msg, const char& arg,
ostream& out = *eout) { (*this)(MAJOR, msg, arg, out); }
/**
* Same as above but handles an unsigned character for the argument
*/
void operator()(const string msg, const unsigned char& arg,
ostream& out = *eout) { (*this)(MAJOR, msg, arg, out); }
/**
* Same as above but handles character string for the argument.
*/
void operator()(const string msg, const string arg = SM_NULL,
ostream& out = *eout) { (*this)(MAJOR, msg, arg, out); }
/**
* This method can be called either by an object or directly within the
* class by "Error::setOuput(ostream)". This powerful method changes the
* output ostream for all Error objects.
*
* @param newout New ostream for all error message outputs
*/
static void setOutput(ostream& newout) { eout = &newout; }
/**
* This method can be called either by an object or directly within the
* class by "Error::setHeader(header)". This powerful method changes the
* header and/or boarder for all Error objects.
*
* @param newheader New header
* @param newboarder New header boarder
*/
static void setHeader(const string newheader,
const string newboarder = eboarder);
private:
static ostream* eout;
static string eheader;
static string eboarder;
ErrLevel lvl;
int num;
};
/**
* Helper function to allow compares between error levels.
*
* see @ref ErrLevel
*/
bool operator==(ErrLevel, ErrLevel);
} // namespace StatusMsgs //
#endif
| Generated on Fri Mar 9 02:04:42 2001, using kdoc 2.0a43. |