utils/debugparse.c

説明を見る。
00001 /* ========================================================================== **
00002  *                                debugparse.c
00003  *
00004  * Copyright (C) 1998 by Christopher R. Hertel
00005  *
00006  * Email: crh@ubiqx.mn.org
00007  *
00008  * -------------------------------------------------------------------------- **
00009  * This module is a very simple parser for Samba debug log files.
00010  * -------------------------------------------------------------------------- **
00011  *
00012  *  This library is free software; you can redistribute it and/or
00013  *  modify it under the terms of the GNU Library General Public
00014  *  License as published by the Free Software Foundation; either
00015  *  version 2 of the License, or (at your option) any later version.
00016  *
00017  *  This library is distributed in the hope that it will be useful,
00018  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00019  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020  *  Library General Public License for more details.
00021  *
00022  *  You should have received a copy of the GNU Library General Public
00023  *  License along with this library; if not, write to the Free
00024  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00025  *
00026  * -------------------------------------------------------------------------- **
00027  * The important function in this module is dbg_char2token().  The rest is
00028  * basically fluff.  (Potentially useful fluff, but still fluff.)
00029  * ========================================================================== **
00030  */
00031 
00032 #include "debugparse.h"
00033 
00034 /* -------------------------------------------------------------------------- **
00035  * Constants...
00036  *
00037  *  DBG_BSIZE - This internal constant is used only by dbg_test().  It is the
00038  *          size of the read buffer.  I've tested the function using a
00039  *          DBG_BSIZE value of 2.
00040  */
00041 
00042 #define DBG_BSIZE 128
00043 
00044 /* -------------------------------------------------------------------------- **
00045  * Functions...
00046  */
00047 
00048 const char *dbg_token2string( dbg_Token tok )
00049   /* ------------------------------------------------------------------------ **
00050    * Given a token, return a string describing the token.
00051    *
00052    *  Input:  tok - One of the set of dbg_Tokens defined in debugparse.h.
00053    *
00054    *  Output: A string identifying the token.  This is useful for debugging,
00055    *          etc.
00056    *
00057    *  Note:   If the token is not known, this function will return the
00058    *          string "<unknown>".
00059    *
00060    * ------------------------------------------------------------------------ **
00061    */
00062   {
00063   switch( tok )
00064     {
00065     case dbg_null:
00066       return( "null" );
00067     case dbg_ignore:
00068       return( "ignore" );
00069     case dbg_header:
00070       return( "header" );
00071     case dbg_timestamp:
00072       return( "time stamp" );
00073     case dbg_level:
00074       return( "level" );
00075     case dbg_sourcefile:
00076       return( "source file" );
00077     case dbg_function:
00078       return( "function" );
00079     case dbg_lineno:
00080       return( "line number" );
00081     case dbg_message:
00082       return( "message" );
00083     case dbg_eof:
00084       return( "[EOF]" );
00085     }
00086   return( "<unknown>" );
00087   } /* dbg_token2string */
00088 
00089 dbg_Token dbg_char2token( dbg_Token *state, int c )
00090   /* ------------------------------------------------------------------------ **
00091    * Parse input one character at a time.
00092    *
00093    *  Input:  state - A pointer to a token variable.  This is used to
00094    *                  maintain the parser state between calls.  For
00095    *                  each input stream, you should set up a separate
00096    *                  state variable and initialize it to dbg_null.
00097    *                  Pass a pointer to it into this function with each
00098    *                  character in the input stream.  See dbg_test()
00099    *                  for an example.
00100    *          c     - The "current" character in the input stream.
00101    *
00102    *  Output: A token.
00103    *          The token value will change when delimiters are found,
00104    *          which indicate a transition between syntactical objects.
00105    *          Possible return values are:
00106    *
00107    *          dbg_null        - The input character was an end-of-line.
00108    *                            This resets the parser to its initial state
00109    *                            in preparation for parsing the next line.
00110    *          dbg_eof         - Same as dbg_null, except that the character
00111    *                            was an end-of-file.
00112    *          dbg_ignore      - Returned for whitespace and delimiters.
00113    *                            These lexical tokens are only of interest
00114    *                            to the parser.
00115    *          dbg_header      - Indicates the start of a header line.  The
00116    *                            input character was '[' and was the first on
00117    *                            the line.
00118    *          dbg_timestamp   - Indicates that the input character was part
00119    *                            of a header timestamp.
00120    *          dbg_level       - Indicates that the input character was part
00121    *                            of the debug-level value in the header.
00122    *          dbg_sourcefile  - Indicates that the input character was part
00123    *                            of the sourcefile name in the header.
00124    *          dbg_function    - Indicates that the input character was part
00125    *                            of the function name in the header.
00126    *          dbg_lineno      - Indicates that the input character was part
00127    *                            of the DEBUG call line number in the header.
00128    *          dbg_message     - Indicates that the input character was part
00129    *                            of the DEBUG message text.
00130    *
00131    * ------------------------------------------------------------------------ **
00132    */
00133   {
00134   /* The terminating characters that we see will greatly depend upon
00135    * how they are read.  For example, if gets() is used instead of
00136    * fgets(), then we will not see newline characters.  A lot also
00137    * depends on the calling function, which may handle terminators
00138    * itself.
00139    *
00140    * '\n', '\0', and EOF are all considered line terminators.  The
00141    * dbg_eof token is sent back if an EOF is encountered.
00142    *
00143    * Warning:  only allow the '\0' character to be sent if you are
00144    *           using gets() to read whole lines (thus replacing '\n'
00145    *           with '\0').  Sending '\0' at the wrong time will mess
00146    *           up the parsing.
00147    */
00148   switch( c )
00149     {
00150     case EOF:
00151       *state = dbg_null;   /* Set state to null (initial state) so */
00152       return( dbg_eof );   /* that we can restart with new input.  */
00153     case '\n':
00154     case '\0':
00155       *state = dbg_null;   /* A newline or eoln resets to the null state. */
00156       return( dbg_null );
00157     }
00158 
00159   /* When within the body of the message, only a line terminator
00160    * can cause a change of state.  We've already checked for line
00161    * terminators, so if the current state is dbg_msgtxt, simply
00162    * return that as our current token.
00163    */
00164   if( dbg_message == *state )
00165     return( dbg_message );
00166 
00167   /* If we are at the start of a new line, and the input character 
00168    * is an opening bracket, then the line is a header line, otherwise
00169    * it's a message body line.
00170    */
00171   if( dbg_null == *state )
00172     {
00173     if( '[' == c )
00174       {
00175       *state = dbg_timestamp;
00176       return( dbg_header );
00177       }
00178     *state = dbg_message;
00179     return( dbg_message );
00180     }
00181 
00182   /* We've taken care of terminators, text blocks and new lines.
00183    * The remaining possibilities are all within the header line
00184    * itself.
00185    */
00186 
00187   /* Within the header line, whitespace can be ignored *except*
00188    * within the timestamp.
00189    */
00190   if( isspace( c ) )
00191     {
00192     /* Fudge.  The timestamp may contain space characters. */
00193     if( (' ' == c) && (dbg_timestamp == *state) )
00194       return( dbg_timestamp );
00195     /* Otherwise, ignore whitespace. */
00196     return( dbg_ignore );
00197     }
00198 
00199   /* Okay, at this point we know we're somewhere in the header.
00200    * Valid header *states* are: dbg_timestamp, dbg_level,
00201    * dbg_sourcefile, dbg_function, and dbg_lineno.
00202    */
00203   switch( c )
00204     {
00205     case ',':
00206       if( dbg_timestamp == *state )
00207         {
00208         *state = dbg_level;
00209         return( dbg_ignore );
00210         }
00211       break;
00212     case ']':
00213       if( dbg_level == *state )
00214         {
00215         *state = dbg_sourcefile;
00216         return( dbg_ignore );
00217         }
00218       break;
00219     case ':':
00220       if( dbg_sourcefile == *state )
00221         {
00222         *state = dbg_function;
00223         return( dbg_ignore );
00224         }
00225       break;
00226     case '(':
00227       if( dbg_function == *state )
00228         {
00229         *state = dbg_lineno;
00230         return( dbg_ignore );
00231         }
00232       break;
00233     case ')':
00234       if( dbg_lineno == *state )
00235         {
00236         *state = dbg_null;
00237         return( dbg_ignore );
00238         }
00239       break;
00240     }
00241 
00242   /* If the previous block did not result in a state change, then
00243    * return the current state as the current token.
00244    */
00245   return( *state );
00246   } /* dbg_char2token */
00247 
00248 void dbg_test( void );
00249 void dbg_test( void )
00250   /* ------------------------------------------------------------------------ **
00251    * Simple test function.
00252    *
00253    *  Input:  none.
00254    *  Output: none.
00255    *  Notes:  This function was used to test dbg_char2token().  It reads a
00256    *          Samba log file from stdin and prints parsing info to stdout.
00257    *          It also serves as a simple example.
00258    *
00259    * ------------------------------------------------------------------------ **
00260    */
00261   {
00262   char bufr[DBG_BSIZE];
00263   int  i;
00264   int  linecount  = 1;
00265   dbg_Token old   = dbg_null,
00266             newtok= dbg_null,
00267             state = dbg_null;
00268 
00269   while( fgets( bufr, DBG_BSIZE, stdin ) )
00270     {
00271     for( i = 0; bufr[i]; i++ )
00272       {
00273       old = newtok;
00274       newtok = dbg_char2token( &state, bufr[i] );
00275       switch( newtok )
00276         {
00277         case dbg_header:
00278           if( linecount > 1 )
00279             (void)putchar( '\n' );
00280           break;
00281         case dbg_null:
00282           linecount++;
00283           break;
00284         case dbg_ignore:
00285           break;
00286         default:
00287           if( old != newtok )
00288             (void)printf( "\n[%05d]%12s: ", linecount, dbg_token2string(newtok) );
00289           (void)putchar( bufr[i] );
00290         }
00291       }
00292     }
00293   (void)putchar( '\n' );
00294   } /* dbg_test */
00295 
00296 
00297 /* -------------------------------------------------------------------------- **
00298  * This simple main line can be uncommented and used to test the parser.
00299  */
00300 
00301 /*
00302  * int main( void )
00303  *  {
00304  *  dbg_test();
00305  *  return( 0 );
00306  *  }
00307  */
00308 
00309 /* ========================================================================== */

Sambaに対してSat Aug 29 21:23:28 2009に生成されました。  doxygen 1.4.7