|
|
/* ------------------------------------------------------------------------- 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. |