/* ** Command & Conquer Generals Zero Hour(tm) ** Copyright 2025 Electronic Arts Inc. ** ** 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 3 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, see . */ /////////////////////////////////////////////////////////////////////////EA-V1 // $File: //depot/GeneralsMD/Staging/code/Libraries/Source/debug/debug_doc.h $ // $Author: mhoffe $ // $Revision: #1 $ // $DateTime: 2003/07/03 11:55:26 $ // // ©2003 Electronic Arts // // additional Doxygen module documentation ////////////////////////////////////////////////////////////////////////////// #ifdef _MSC_VER # pragma once #endif #ifndef DEBUG_DOC_H // Include guard #define DEBUG_DOC_H // This generates a small main page for Doxygen if a module only // documentation is built. #ifndef DOXYGEN_GLOBAL_DOC /** \mainpage %Debug module The following pages contain the most useful information: - \ref module_debug - \ref debug_macros - \ref debug_stream - \ref debug_cmd \internal This is the internal module documentation meant only for programmers who are working on the module internals. */ #endif /** \page module_debug Debug module overview \section overview Overview The Debug module contains all functions necessary to perform debugging related tasks, e.g. checking assertions or logging. \section logging Logging Logging can be sent to a number of different locations: - a flat log file - a console window - a debugger via OutputDebugString - to a remote program (via a named pipe) - to a number of separated log files By default logging is enabled to the flat log file. \section cmd Commands The debug module is controlled via extendable commands. Commands are typically put into logical groups. A command can then be executed in a number of ways: - group.command \ (explicitly specifies which group to use) - command \ (assumes that the command resides in the same group as the previous one) - group. (switches the current group) Every group has to respond to the command 'help'. See also: \ref debug_cmd \section dbgcmd .dbgcmd file On startup the debug module tries to open a file called \.dbgcmd - if found then all lines in this module are directly interpreted as commands. If the file is not found then default.dbgcmd is tried instead. This allows for setting up a default environment. */ /** \page debug_cmd Debug commands Notation used: - [ abc ] means that 'abc' may or may not be specified - { abc } means that 'abc' may be specified any number of times (or not at all) - (a|b|c) means that either 'a', 'b' or 'c' must be specified once The following commands are already build in (group: debug):
Command Parameters Description
list (g|l|d|a|c) [ \ ] Shows some or all items of a specific type. The following items are supported: - g: command groups - l: log groups (only those encountered yet) - d: log groups with descriptions (only those that have descriptions) - a: asserts/crashes (only those hit yet) - c: checks (only those failed yet) If a pattern is specified only items matching that pattern are shown. A pattern can contain any character, letter, or a wildcard '*'. Please note that assert, crashes, and check items have their line number appended to the current file name, e.g. debug.cpp(13). Example: \code > list g debug > list l test* test test_log2 > list d test* test_log2: test log group w/ description \endcode
help Shows help regarding debug group commands. Example: \code > help Help info debug group: ... \endcode
io [ \ \ { \ }] Issues a I/O class command. I/O class commands are used for determining where all log output should be sent. Please check the list of \ref debug_ioclasses for a list of existing I/O classes. Each existing I/O class must accept at least the following two commands: 'add' and 'remove'. Parameters for these commands and additional commands are defined on this page: \ref debug_ioclasses If the command is entered without any parameters a list of active I/O classes is shown. Typing 'io ?' retrieves a list of possible I/O classes. Example: \code > io Active: flat (flat log file) ods (OutputDebugString) > io ods remove > io ? Possible: flat (flat/split log file) con (console window) ods (OutputDebugString) net (Network destination via named pipe) \endcode
alwaysflush [ (+|-) ] Enables/disables flushing after each new entry in the log file (default: off) Example: \code > alwaysflush + Flush: on \endcode
timestamp [ (+|-) ] Enables/disables timestamping each log entry (default: off). Example: \code > timestamp + Timestamping: on \endcode
exit Exits program immediately.
clear (l|a|c) Clears the given inclusion/exclusion list (l=logs, a=asserts/crashes, c=checks).
add (l|a|c) (+|-) \ Adds a pattern to the given list (l=logs, a=asserts/crashes, c=checks). By default all asserts, crashes, and checks are active, all logs inactive. Each item is then checked against all pattern in the respective list. If a match is found the active/inactive state is modified accordingly (+ for active, - for inactive). The final state is always the last match. Example: \code > clear l > add l + test* > add l - *45* \endcode This would now enable logging on all log groups that start with 'test' but don't have '45' in the group name.
view [ (l|a|c) ] Shows the active pattern for the given list (l=logs, a=asserts/crashes, c=checks).
*/ /** \addtogroup debug_stream Debug and Logging stream The Debug class can act as an output stream for debugging and logging purposes. This is used e.g. for displaying custom messages in a failed DASSERT_MSG statement or for logging data. There are a number of reasons why this module implements this in a stream-like fashion instead of the 'usual' printf method: - type safety: using a streams-like approach makes logging statements type safe. No more crashes in an ASSERT or log statement because the parameter specifiers in the printf format string didn't match with the values actually given. - extensibility: new stream operators can be implemented outside of the debug module Syntactically the Debug class acts almost like a ostream class: \code int n=1; float f=4; DLOG( "This is a static string and some other stuff: " << n << " " << f << "\n" ); \endcode New types can be added easily, e.g.: \code struct Point2D { int x,y; }; inline Debug& operator<<(Debug& debug, const Point2D &pt) { debug << "(" << pt.x << ";" << pt.y << ")"; return debug; } void test(const Point2D &val) { DLOG( "Current point value is " << val << "\n" ); DASSERT_MSG( val.x>=0 && val.y>=0, val << " is invalid"); } \endcode Please note that all these operators should not be cluttered with any #ifdef _DEBUG or similar conditional compile statements. It is not necessary to remove these operators from the code in release builds (just don't forget to add 'inline' before the operator though). In addition there are a number of helper classes declared inside of Debug: - Debug::MemDump provides functions for inserting a raw memory dump into the Debug stream - Debug::HResult dumps out a HRESULT value plus additionally calling custom translator functions */ /** \page debug_ioclasses Debug I/O classes The %Debug module defines a number of pre-existing I/O classes. New classes can be developed and added. An I/O class can have additional commands and parameters. This section lists the existing I/O classes and their additional commands and parameters. The initial part of the command ('io \') is omitted here. \section debug_ioc_flat flat (flat or split log file) By default all data is written into a single flag log file. Optionally the size of this log file may be limited (implemented by using a memory based ring buffer).
I/O Command Parameters Description
add [ \ [ \ ] ] Adds the flat I/O class. If a filename is specified all output is written to that file. Otherwise the filename \-\.log (resp. \-\-\.log) is automatically used. Any existing files with that name are overwritten. Instead of a real file name a 'magic' file name can be used by starting the file name with a '*' followed by any number of special characters: - 'e': inserts EXE name - 'm': inserts machine name - 'u': inserts username - 't': inserts timestamp - 'n': inserts split name (empty if main log file) - '-': inserts '-' - 'E', 'M', 'U', 'T', 'N': same as above but with '-' in front (for 'N': empty if main log file) .log is automatically appended if using magic file names. So basically 'add' and 'and *eMN' are identical. If a size is specified then all data is internally written to a fixed size memory based ring buffer. This data is flushed out once the program exits. If no size is given then the size of the log file is not limited and any log data is written out immediately.
copy \ Copies generated log file(s) into the given directory if the program exists or crashes. If there is already a log file with the same name a unique number is appended to the current log files' name.
splitadd \ \ \ [ \ ] Splits off part of the log data. Multiple splits can be defined. They are written out to the first matching split file. 'types' defines one or more string types which should be split off: - a: asserts/crashes - c: checks - l: logs - h: crash - x: exceptions - r: replies from commands - o: other messages Next a filter is specified that determines which items are to be filtered (only for string types a, c and l). Items can be listed with then 'list' command. The filter is exactly specified as in that command. The third parameter defines a name for this split. If there is already a split with the same name then both will write to the same destination file. Note: If splits are used and the filename given for 'add' is static then the split name is automatically appended to the log file name (before the extension). If a size is specified then all data is internally written to a fixed size memory based ring buffer. This data is flushed out once the program exits. If no size is given then the size of the log file is not limited and any log data is written out immediately.
splitview Shows all existing splits in the order they are evaluated.
splitremove \ Removes all active splits matching the given name pattern.
\section debug_ioc_con con (console window)
I/O Command Parameters Description
add % Adds the console window as log output. A new console window is created (if it doesn't exist already).
\section debug_ioc_ods ods (OutputDebugString, for use in debugger)
I/O Command Parameters Description
add % %Debug output is sent via OutputDebugString.
\section debug_ioc_net net (Network destination via named pipe)
I/O Command Parameters Description
add \ Tells system which computer to connect to for remote logging. By default this is the local machine. The debug module tries to connect to a named pipe \\\\\\\pipe\\ea_debug_v1.
*/ /** \page debug_structcmd Structured command reply \section debug_structcmd_overview Overview All commands are capable of returning replies in two differnt forms: A regular reply or a structured reply. A structured reply is basically like the regular reply but with three differences: - Structured reply string type \ref DebugIOInterface::StructuredCmdReply - There is a 1:1 mapping between command and result i.e. no matter how long a command result is there will always be only one call to the \ref DebugIOInterface::Write method for that result. - The result format is fixed for any given command i.e. it must not change. A structured reply is given if the command is invoked with a '!' as first character. The motivation behind having structured command replies is to make it possible to hide some of the debug command complexity behind a UI. \section debug_structcmd_list List of structured command replies for debug command group The reply for a structured command always consists of first repeating the given command, a CR and then additional optional reply data.
Command Reply
list \ CR
...
\ CR
help regular reply format (unstructured)
io, io ? \ CR
...
\ CR
io \ '1' CR (if command ok)
'0' \ CR (if command failed)
alwaysflush '1' CR (if flush on)
'0' CR (if flush off)
timestamp '1' CR (if timestamp on)
'0' CR (if timestamp off)
exit none
clear none
add none
view \ CR
...
\ CR
*/ #endif // DEBUG_DOC_H