summaryrefslogtreecommitdiffstats
path: root/source/lib/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/lib/debug.c')
-rw-r--r--source/lib/debug.c160
1 files changed, 159 insertions, 1 deletions
diff --git a/source/lib/debug.c b/source/lib/debug.c
index 3a90da2f3d2..ab11d81a212 100644
--- a/source/lib/debug.c
+++ b/source/lib/debug.c
@@ -125,7 +125,6 @@ static int format_pos = 0;
* tells us if interactive logging was requested
* ************************************************************************** **
*/
-
BOOL dbg_interactive(void)
{
return stdout_logging;
@@ -597,4 +596,163 @@ BOOL dbghdr( int level, char *file, char *func, int line )
#endif
+dbg_Token dbg_char2token( dbg_Token *state, int c )
+ /* ************************************************************************ **
+ * Parse input one character at a time.
+ *
+ * Input: state - A pointer to a token variable. This is used to
+ * maintain the parser state between calls. For
+ * each input stream, you should set up a separate
+ * state variable and initialize it to dbg_null.
+ * Pass a pointer to it into this function with each
+ * character in the input stream. See dbg_test()
+ * for an example.
+ * c - The "current" character in the input stream.
+ *
+ * Output: A token.
+ * The token value will change when delimiters are found,
+ * which indicate a transition between syntactical objects.
+ * Possible return values are:
+ *
+ * dbg_null - The input character was an end-of-line.
+ * This resets the parser to its initial state
+ * in preparation for parsing the next line.
+ * dbg_eof - Same as dbg_null, except that the character
+ * was an end-of-file.
+ * dbg_ignore - Returned for whitespace and delimiters.
+ * These lexical tokens are only of interest
+ * to the parser.
+ * dbg_header - Indicates the start of a header line. The
+ * input character was '[' and was the first on
+ * the line.
+ * dbg_timestamp - Indicates that the input character was part
+ * of a header timestamp.
+ * dbg_level - Indicates that the input character was part
+ * of the debug-level value in the header.
+ * dbg_sourcefile - Indicates that the input character was part
+ * of the sourcefile name in the header.
+ * dbg_function - Indicates that the input character was part
+ * of the function name in the header.
+ * dbg_lineno - Indicates that the input character was part
+ * of the DEBUG call line number in the header.
+ * dbg_message - Indicates that the input character was part
+ * of the DEBUG message text.
+ *
+ * ************************************************************************ **
+ */
+ {
+ /* The terminating characters that we see will greatly depend upon
+ * how they are read. For example, if gets() is used instead of
+ * fgets(), then we will not see newline characters. A lot also
+ * depends on the calling function, which may handle terminators
+ * itself.
+ *
+ * '\n', '\0', and EOF are all considered line terminators. The
+ * dbg_eof token is sent back if an EOF is encountered.
+ *
+ * Warning: only allow the '\0' character to be sent if you are
+ * using gets() to read whole lines (thus replacing '\n'
+ * with '\0'). Sending '\0' at the wrong time will mess
+ * up the parsing.
+ */
+ switch( c )
+ {
+ case EOF:
+ *state = dbg_null; /* Set state to null (initial state) so */
+ return( dbg_eof ); /* that we can restart with new input. */
+ case '\n':
+ case '\0':
+ *state = dbg_null; /* A newline or eoln resets to the null state. */
+ return( dbg_null );
+ }
+
+ /* When within the body of the message, only a line terminator
+ * can cause a change of state. We've already checked for line
+ * terminators, so if the current state is dbg_msgtxt, simply
+ * return that as our current token.
+ */
+ if( dbg_message == *state )
+ return( dbg_message );
+
+ /* If we are at the start of a new line, and the input character
+ * is an opening bracket, then the line is a header line, otherwise
+ * it's a message body line.
+ */
+ if( dbg_null == *state )
+ {
+ if( '[' == c )
+ {
+ *state = dbg_timestamp;
+ return( dbg_header );
+ }
+ *state = dbg_message;
+ return( dbg_message );
+ }
+
+ /* We've taken care of terminators, text blocks and new lines.
+ * The remaining possibilities are all within the header line
+ * itself.
+ */
+
+ /* Within the header line, whitespace can be ignored *except*
+ * within the timestamp.
+ */
+ if( isspace( c ) )
+ {
+ /* Fudge. The timestamp may contain space characters. */
+ if( (' ' == c) && (dbg_timestamp == *state) )
+ return( dbg_timestamp );
+ /* Otherwise, ignore whitespace. */
+ return( dbg_ignore );
+ }
+
+ /* Okay, at this point we know we're somewhere in the header.
+ * Valid header *states* are: dbg_timestamp, dbg_level,
+ * dbg_sourcefile, dbg_function, and dbg_lineno.
+ */
+ switch( c )
+ {
+ case ',':
+ if( dbg_timestamp == *state )
+ {
+ *state = dbg_level;
+ return( dbg_ignore );
+ }
+ break;
+ case ']':
+ if( dbg_level == *state )
+ {
+ *state = dbg_sourcefile;
+ return( dbg_ignore );
+ }
+ break;
+ case ':':
+ if( dbg_sourcefile == *state )
+ {
+ *state = dbg_function;
+ return( dbg_ignore );
+ }
+ break;
+ case '(':
+ if( dbg_function == *state )
+ {
+ *state = dbg_lineno;
+ return( dbg_ignore );
+ }
+ break;
+ case ')':
+ if( dbg_lineno == *state )
+ {
+ *state = dbg_null;
+ return( dbg_ignore );
+ }
+ break;
+ }
+
+ /* If the previous block did not result in a state change, then
+ * return the current state as the current token.
+ */
+ return( *state );
+ } /* dbg_char2token */
+
/* ************************************************************************** */