//---------------------------------------------------------------------------
JrDebug Readme
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// Version History:
//  see help file
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
// Tested with the following compilers:
//  1. MS Visual C++ .Net2003 (7.1)			1.01.17* (main testing platform)
//  2. MS Visual C++ 6						1.01.12
//  3. Intel C++							1.01.12
//  4. Borland C++							1.01.12
//  5. Borland C++ Builder 6				1.02.01
//  6. Dev-C++ (mingw32)					1.01.12
//  7. Digital Mars							1.01.12
//  8. Cygwin Gcc							1.01.12
//  9. Linux Gcc							1.01.12
//  10.Greenhills C++						1.01.12
//  11.Metroworks CodeWarrior				1.01.12
//  12.Comeau (using bcc)					1.01.12
//  13. Codegear C++ Builder 11 / RAD Studio 2007			1.07.01
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// ToDo:
//  make it thread safe
//  add support for unicode text
//  write new gui mode (hierarchical db)
//  write tester gui
//  write piped output code for *nix
//  benchmark memory and cpu
//  update documentation
//  add some compiler-specific hints
//  find better way to detect snprintf vs. _snprintf
//  add stdout summaries of each test, for picking up from tester gui
//  should exceptions not get treated as errors?
//  add support for specifying tests to run by name as well as keyword (fix keyword matching)
//  improve version announcement (include compiler info, date, exename, jrdebug version)
//  remove ATTN: extra comments that are out of date
//  add file Ahref links to html output (and smart linking via gui tester)
//  update gui tool icons
//  add template wrappers for registering test functions with return values and parameters
//  fix strange bug in gui monitor tool where incoming messages get stored wrong
//  make callback objects self-register
//  retest new stuff on different compilers
//  flush output after each message (files not updating till exit)?
//  fix subsystem:windows console output to send to current console if one is opened rather than open new
//  windows console opened for output is too small, buffer history gets lost (can we fix and is there other console flush settings we want)
//   should we implement a custom pop up log viewer for windows? (ie richedit) (ie -dbo ;winform)?
//  test with -wall and -ansi and other strict warnings
//  add more shortcut macros for different levels of output to make it easier to filter out annoyances
//   add enums for common levels (ie HighLevel,LowLevel,MedLevel,ErrorLevel,WarnLevel,etc.)
//   ie debugoutlow (dbprintflow) , debugouthigh (debugprintfhigh) for low and high priority
//   and add -dbf to set filter level (low, norm, high) (0,50,100)
//  add file size limits for -dbo output
//  add a column for reporting os+process specific info like thread id
//  add ability to specify for each instantiated formatter object to be told which fields to display/hids
//  add object / stl hex-dumping
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
// OTHER ACCESSORY TOOLS INCLUDED WITH JrDebug:
//  1. A custom GUI monitoring/viewing utility that knows how to parse the JrDebug
//     generated debug messages exists for MS Windows and provides a convenient
//     way to view, sort, and filter debug messages (C++ Builder).
//  2. A component for catching debug messages has (C++ Builder).
//  3. A custom GUI tool for running tests (C++ Builder).
//---------------------------------------------------------------------------






//---------------------------------------------------------------------------
// Customization:
//  See the file "jrdebug_switch.h" for switches you may want to play with,
//---------------------------------------------------------------------------






//---------------------------------------------------------------------------
// Basic Usage Instructions
// -------------------------
//  Include this header file in all of your source code files that you want
//   to use debug output in.  Then include the file jrdebug_main.cpp
//   *once* and only once (usually in your main.cpp)
//
//  Then just make calls to JrDebugPrintf (or the short version dbprintf) as
//   you  would a normal printf statement.  If debugging is enabled, this line
//   will be sent via Windows OutputDebugString debugging protocol, or
//   to stderr if compiled under non-windows OS.  Extra info about location
//   in code will be added automatically.
//
//  ex:
//   dbprintf("This is a debugging message.");
//  OR use the stream-style output ex:
//   debugout << "This is a debugging message.";
//
//  resulting debug output:
//   "|*RunId*| 1091904190 |*TimeStamp*| 1091904193 |*Index*| 1 |*Type*| Message |*Level*| 50 |*File*| ".\src\learningmodule.cpp" (Fri Aug  6 16:50:18 2004) |*Line*| 1118 |*Func*| LearningModule::ReceiveSpecialSignal |*Message*| This is a debugging message."
//
//  The extra info added includes filename, file line, and some other info, in
//   a format designed to be both human+machine readable.
//  You can use any format modifiers and arguments that you would use with
//   printf (if you want to output a c++ string you can use dprints instead).
//
//  NOTE: Defining the JrDebugDIRECTIVE_DontCompileDebugging macro in your code
//   will eliminate all debugging code, and result in no wasted overhead in
//   executing any debug statements.  This code was also designed to have a
//   very minimal impact on performance if it is compiled in but disabled.
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
// Intermediate Usage Instructions
// --------------------------------
//  In addition to the standard dbprintf(..) format, you are encouraged to
//   use the more informative extended format, which adds fields for messagetype,
//   submessagetype, activitystring, and severity level.
//
//  void dbprintf(const JrdType inmtype const int inseverity=50, const char* format, ... )
//  ex:
//   dbprintf(JrdWarning,50,"This is a debugging message.");
//   dbprintf(JrdWarning,"This is a debugging message.");
//  resulting debug output:
//   "|*RunId*| 1091904190 |*TimeStamp*| 1091904193 |*Index*| 1 |*Type*| Warning |*Level*| 50 |*File*| ".\src\learningmodule.cpp" (Fri Aug  6 16:50:18 2004) |*Line*| 1118 |*Func*| LearningModule::ReceiveSpecialSignal |*Message*| This is a debugging message."
//
// or
//
//  void dbprintf(const JrdType inmtype , const char *dmsubtypestr, const char *inactivity, const int inseverity, const char* format, ... )
//  ex:
//   dbprintf(JrdWarning,"minor","testing",10,"This is a debugging message.");
//  resulting debug output:
//   "|*RunId*| 1091904190 |*TimeStamp*| 1091904193 |*Index*| 1 |*Type*| Warning.minor |*Level*| 10 |*Activity*| testing |*File*| ".\src\learningmodule.cpp" (Fri Aug  6 16:50:18 2004) |*Line*| 1118 |*Func*| LearningModule::ReceiveSpecialSignal |*Message*| This is a debugging message."
//
//  JrdType can be from: { JrdMessage, JrdWarning, JrdError, JrdAlarm, JrdNote , JrdTest , JrdCustom}
//---------------------------------------------------------------------------
//
// Stream Mode Usage
// ------------------
//  You can use more modern stream style debug logging instead of the printf style if you prefer.
//  Use the JrDebugStream (or debugout for short) stream as you would any other stream:
//    debugout << jrd_stdstringT("This is a loop iteration number ") << count;
//  In addition, you can specify some optional parameters by passing them as follows:
//    debugout(JrdWarning) << jrd_stdstringT("This is a loop iteration number ") << count;
//  Parameters available are the same as in the printf version:
//    (const JrdType inmtype const int inseverity=50, const char* format, ... )
//    or (const JrdType inmtype , const char *dmsubtypestr, const char *inactivity, const int inseverity, const char* format, ... )
//---------------------------------------------------------------------------



//---------------------------------------------------------------------------
// Advanced Usage Instructions
// --------------------------------
//  There are a number of global/static properties you can manipulate.
//
//  Activities:
//    The debugger can maintain a stack of current activities and annotate all
//    output with the current activity hierarchy. This can be useful in
//    tracking recursive operations or nested function calls.
//	JrDebug::SetActivity(const char *inactivity);
//	JrDebug::PushActivity(const char *inactivity);
//	JrDebug::PopActivity(const char *inactivity);
//
//  Debug Block Activities
//     You can use automatically scoped debugblock helpers to time blocks
//     A block will announce start and end and elapsed time
//     A report can be used within a block to display current time offset
//  JrDebugBlock(const char *label);
//  JrDebugBlockReport(const char *label);
//
//  File Logging:
//    You can ask the debugger to log all messages to a disk file:
//      JrDebug::WriteToFilename(char *fname,bool appendmode);
//     use appendmode==true to append to any existing file, or false to overwrite.
//     by default logging occurs to both file and debug stream if this is enabled.
//
//  Filtering:
//    You can disable and limit logging at runtime:
//		JrDebug::SetFilterLevelRange(int min,int max);
//		JrDebug::SetEnabled(bool val);
//		JrDebug::SetEnabledFile(bool val);
//		JrDebug::SetEnabledStandard(bool val);
//		JrDebug::SetEnabledStdout(bool val);
//
//  Assertions:
//    When JrDebugging is enabled, JrDebug takes over the normal assert()
//     and verify() macros, sending failures to the debug log before exiting
//     the application.  The assertion failure message is sent to both stdout
//     and stderr, and a windows MessageBox is shown if compiled on windows.
//    By default, asssertions that are not violated are not displayed, but
//     you can change this by calling:
//		JrDebug::SetDisplayPassingAsserts(bool val);
//
//    If JrDebug compilation is disabled (see macro at top of file),
//     then the normal assert and verify macros are invoked.
//
//  Helper Functions:
//     To help you add optional debugging to your app via a commmanline parameter,
//      you can use the following function call from your main procedure (see demo):
//       bool JrDebug::GrabCommandlineDebugFile(int &argc,char **argv,bool disableifnofile=false, bool dontchangeargcv=false)
//     That call will look for parameter(s) of the form '-dbf [filename]' on
//      the commandline (and strip them if found, modifying argc), and
//      then enable debugging and writes output to the file specified
//      (or jrdebugout.log by default).  Pass a 3rd parameter of true to this
//      function to disable logging if parameter not found.  In this way,
//      your program will run without debugging unless -dbf is passed on the
//      commandline.
//     You might also want to include a call to:
//       void JrDebug::Announce(char* appdescription,bool evenifdisabled=true,int argc=0, char **argv=NULL)
//      which will generate a log line describing that JrDebug is running and its version #
// 
// Alarms:
//  If you use the JrdAlarm type in any message, a messagebox will also be shown to user on windows platforms.
//  You can also set a global alarm level via JrDebug::SetAlarmFilterLevel(int)
//   any message with severity level >= that level will trigger a messagebox.
//
// Exception Logging:
//  JrDebugThrow (dbthrow) is a replacement for the normal throw command (though note
//   that it uses a different calling convention:  JrDebugThrow(exception X, char * Y)
//  This will cause the normal exception, and will generate a logging message beforehand.
//  Exception logging is disabled by default, you can enable it with:
//   JrDebug::EnableExceptionLogging(int exceptionlevel=50);
//   exceptionlevel specifies the severity level assigned to exception messages (combine with Alarms to get popup messageboxes)
//  You can redisable with:
//   JrDebug::DisableExceptionLogging();
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// New unit testing functions
//  I haven't written proper documentation for the unit testing support functions yet;
//   and more output formats are needed to make these more pleasant to use, but
//   you can get a feel for how to do testing by looking at demo sample #9.
//---------------------------------------------------------------------------


//---------------------------------------------------------------------------
// Commandline Functionality
//
//  -dbol
//    list all available output styles
//
//  -dbo STYLE[:options][;FILENAME][;stdout][;sysout]
//   where STYLE is one of the outout styles (xml,html,comp,text,jrd)
//   and fields after the STYLE separated by ; represent output targets
//    FILENAME can contain some special flags (use "" to quote spaces):
//     Full Date: $DATE
//     Year: $YYYY, $YY
//     Month: $MMM, $MM, $M
//     Day: $DDD, $D
//     Unique Number: $#####, $####, $###, $##, $#
//     Executable Name: $EXE
//  if filename ends in -a then it will be opened in append mode (e.g. log.txt-a) otherwise existing contents will be overwritten.
//
//
//
//  -dbd
//    disable debugging
//
//  -dbtl [KEYWORD[;KEYWORD]+]
//    list available tests (that match keyword)
//
//  -dbt [|KEYWORD[;KEYWORD]+]
//    run available tests (that match any keyword)
//
//  -dbf [filteroptions]
//    set filter based on options (ex. -dbf eb):
//       e = onlyshowerrors
//       b = show all blocks
//
//
// Examples:
//   myapp.exe -dbo xml;test.xml?stdout
//   myapp.exe -dbo html;results_$EXE_$MONTH_$###.html
//   myapp.exe -dbo jrd;sysout
//   myapp.exe -dbo comp:gcc;"C:\results.txt"
//---------------------------------------------------------------------------








