PRODUCT : Borland C++ NUMBER : 1566 VERSION : All OS : All DATE : October 25, 1993 PAGE : 1/4 TITLE : Creating an error log stream //---------------------------------------------------------- // // errlog.cpp // // This file demonstrates redirecting clog to a text file // for logging error messages. // //---------------------------------------------------------- #include // open, close #include // O_CREAT, O_RDWR #include // S_IREAD, S_IWRITE #include // sprintf #include // cout, clog, cerr #include // filebuf, ofstream #include // strcpy //---------------------------------------------------------- // // User-defined types // //---------------------------------------------------------- // none //---------------------------------------------------------- // // Function prototypes // //---------------------------------------------------------- void CLOG( char * file, unsigned line, char * msg ); void CERR( char * file, unsigned line, char * msg ); //---------------------------------------------------------- // // Macros to simplify logging and error reporting while // retaining proper filename and line number information. // There should be no need for the programmer to call CLOG // and CERR directly. //---------------------------------------------------------- #define LOG(p) CLOG( __FILE__, __LINE__, p ); PRODUCT : Borland C++ NUMBER : 1566 VERSION : All OS : All DATE : October 25, 1993 PAGE : 2/4 TITLE : Creating an error log stream #define ERR(p) CERR( __FILE__, __LINE__, p ); //---------------------------------------------------------- // // Globals and constants // //---------------------------------------------------------- const char logFileName[] = "logfile.dat"; //----------------------------------------------------------- // // The example program redirects clog to an output file, and // logs all events. If a command-line parameter specifies a // file, then cerr is redirected to that fle. // //----------------------------------------------------------- int main( int argc, char ** argv ) { char msgBfr[100]; int logFile=0, errFile=0; filebuf * oldCerrBuf, * oldClogBuf; filebuf * newCerrBuf, * newClogBuf; // Redirect clog to a file. oldClogBuf = (filebuf*) clog.rdbuf(); logFile = open( logFileName, O_CREAT | O_RDWR, S_IREAD | S_IWRITE ); newClogBuf = new filebuf( logFile ); clog.flush(); clog = newClogBuf; // Say hello. sprintf( msgBfr, "Testing %s {%s %s}", argv[0], __DATE__, __TIME__ ); cout << msgBfr << endl; LOG( msgBfr ); // If a filename is passed, we will redirect cerr to // that file. Note that since we initialized errFile to PRODUCT : Borland C++ NUMBER : 1566 VERSION : All OS : All DATE : October 25, 1993 PAGE : 3/4 TITLE : Creating an error log stream // 0, we will be able to count on it's value to indicate // what has happened: -1 failure to open file // 0 not redirected // >0 error file in use if( argc > 1 ) { oldCerrBuf = (filebuf*) cerr.rdbuf(); errFile = open( argv[1], O_CREAT | O_RDWR, S_IREAD | S_IWRITE ); newCerrBuf = new filebuf( errFile ); cerr.flush(); cerr = newCerrBuf; sprintf( msgBfr, "cerr redirected to %s", argv[1] ); LOG( msgBfr ); } // Pretend something happened. strcpy( msgBfr, "Oh, my. There's an error!" ); cout << "\ncout: " << msgBfr << endl; LOG( msgBfr ); ERR( msgBfr ); // Clean up cerr if necessary. if( errFile > 0 ) { cerr.flush(); cerr = oldCerrBuf; delete newCerrBuf; close( errFile ); LOG( "cerr restored to default" ); } // Demonstrate things are back to normal. strcpy( msgBfr, "Program termination." ); cout << "\ncout: " << msgBfr << endl; LOG( msgBfr ); ERR( msgBfr ); // Reset clog on way out of program. PRODUCT : Borland C++ NUMBER : 1566 VERSION : All OS : All DATE : October 25, 1993 PAGE : 4/4 TITLE : Creating an error log stream clog.flush(); clog = oldClogBuf; delete newClogBuf; close( logFile ); return argc; } //----------------------------------------------------------- // // Log a message with file and line number info. // //----------------------------------------------------------- void CLOG( char * file, unsigned line, char * msg ) { clog << "Log entry: " << file << ", " << line << ": " << msg << endl; } //----------------------------------------------------------- // // Report an error with file and line info. The default for // cerr is the standard output stream. // //----------------------------------------------------------- void CERR( char * file, unsigned line, char * msg ) { cerr << "~Error: " << file << ", " << line << ": " << msg << endl; } DISCLAIMER: You have the right to use this technical information subject to the terms of the No-Nonsense License Statement that you received with the Borland product to which this information pertains.