//----------------------------------------------------------------------------- // Purpose: // Input : *input - // *pairing - // Output : char //----------------------------------------------------------------------------- char *CC_DiscardUntilMatchingCharIncludingNesting( char *input, const char *pairing ) { int nestcount = 1; do { input = CC_ParseToken( input ); if ( strlen( com_token ) <= 0 ) break; if ( strlen( com_token ) == 1 ) { if ( com_token[ 0 ] == pairing[ 0 ] ) { nestcount++; } else if ( com_token[ 0 ] == pairing[ 1 ] ) { nestcount--; } } } while ( nestcount != 0 ); return input; }
//----------------------------------------------------------------------------- // Purpose: // Input : *input - // *ch - // *breakchar - // Output : char //----------------------------------------------------------------------------- char *CC_RawParseChar( char *input, const char *ch, char *breakchar ) { bool done = false; int listlen = strlen( ch ); do { input = CC_ParseToken( input ); if ( strlen( com_token ) <= 0 ) break; if ( strlen( com_token ) == 1 ) { for ( int i = 0; i < listlen; i++ ) { if ( com_token[ 0 ] == ch[ i ] ) { *breakchar = ch [ i ]; done = true; break; } } } } while ( !done ); return input; }
bool GetModelNameFromSourceFile( char const *filename, char *modelname, int maxlen ) { modelname[0]=0; int filelength; char *buffer = (char *)COM_LoadFile( filename, &filelength ); if ( !buffer ) { vprint( 0, "Couldn't load %s\n", filename ); return false; } bool valid = false; // Parse tokens char *current = buffer; while ( current ) { current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) break; if ( stricmp( com_token, "$modelname" ) ) continue; current = CC_ParseToken( current ); strcpy( modelname, com_token ); _strlwr( modelname ); Q_FixSlashes( modelname ); Q_DefaultExtension( modelname, ".mdl", maxlen ); valid = true; break; } COM_FreeFile( (unsigned char *)buffer ); if ( !valid ) { vprint( 0, ".qc file %s missing $modelname directive!!!\n", filename ); } return valid; }
char *CCodeProcessor::ParsePredictionTypeDescription( char *current ) { // Next token is open paren, then classname close paren, then { char classname[ 256 ]; char variablename[ 256 ]; current = CC_ParseToken( current ); if (stricmp( com_token, "(" ) ) { return current; } current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) return current; strcpy( classname, com_token ); if ( classname[0]=='*' ) return current; CClass *cl = FindClass( classname ); if ( cl ) { cl->m_bHasPredictionData = true; } current = CC_ParseToken( current ); if (stricmp( com_token, ")" ) ) { return current; } // It's macro-ized strcpy( variablename, "m_PredDesc" ); com_ignoreinlinecomment = true; bool insidecomment = false; // Now parse typedescription line by line while ( 1 ) { current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) break; // Go to next line if ( !stricmp( com_token, "," ) ) continue; // end if ( !stricmp( com_token, "END_PREDICTION_DATA" ) ) break; // skip #ifdef's inside of typedescs if ( com_token[0]=='#' ) { current = CC_ParseUntilEndOfLine( current ); continue; } if ( !stricmp( com_token, "/" ) ) { current = CC_ParseToken( current ); if ( !stricmp( com_token, "/" ) ) { current = CC_ParseToken( current ); if ( !strnicmp( com_token, "DEFINE_", 7 ) ) { CC_UngetToken(); insidecomment = true; } else { current = CC_ParseUntilEndOfLine( current ); } continue; } } com_ignoreinlinecomment = false; // Parse a typedescription line char definetype[ 256 ]; strcpy( definetype, com_token ); current = CC_ParseToken( current ); if ( stricmp( com_token, "(" ) ) break; // skip classname current = CC_ParseToken( current ); if( stricmp( com_token, classname ) ) { vprint( 0, "PREDICTION TYPEDESCRIPTION for class %s uses offset from class %s\n", classname, com_token ); } // skip comma current = CC_ParseToken( current ); char varname[ 256 ]; current = CC_ParseToken( current ); strcpy( varname, com_token ); char vartype[ 256 ]; vartype[0]=0; if ( stricmp( definetype, "DEFINE_FUNCTION" ) ) { // skip comma current = CC_ParseToken( current ); current = CC_ParseToken( current ); strcpy( vartype, com_token ); } else { strcpy( vartype, "funcptr" ); } bool inrecvtable = false; // Jump to end of definition int nParenCount = 1; do { current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) break; if ( !stricmp( com_token, "(" ) ) { ++nParenCount; } else if ( !stricmp( com_token, ")" ) ) { if ( --nParenCount == 0 ) { break; } } if ( !stricmp( com_token, "FTYPEDESC_INSENDTABLE" ) ) { inrecvtable = true; } } while ( 1 ); /* vprint( 2, "%s%s::%s %s %s %s\n", insidecomment ? "// " : "", classname, variablename, definetype, varname, vartype ); */ if ( cl ) { if ( cl->FindPredTD( varname ) ) { vprint( 0, "class %s::%s already has prediction typedescription entry for field %s\n", classname, variablename, varname ); } else { cl->AddPredTD( varname, vartype, definetype, insidecomment, inrecvtable ); } } insidecomment = false; com_ignoreinlinecomment = true; } com_ignoreinlinecomment = false; return current; }
char *CCodeProcessor::ParseReceiveTable( char *current ) { // Next token is open paren, then classname close paren, then { char classname[ 256 ]; current = CC_ParseToken( current ); if (stricmp( com_token, "(" ) ) { return current; } current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) return current; strcpy( classname, com_token ); if ( classname[0]=='*' ) return current; if ( !strcmp( classname, "className" ) ) return current; if ( !strcmp( classname, "clientClassName" ) ) return current; CClass *cl = FindClass( classname ); if ( cl ) { cl->m_bHasRecvTableData = true; } CClass *leafClass = cl; // parse until end of line current = CC_ParseUntilEndOfLine( current ); // Now parse recvtable entries line by line while ( 1 ) { cl = leafClass; current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) break; // Go to next line if ( !stricmp( com_token, "," ) ) continue; // end if ( !stricmp( com_token, "END_RECV_TABLE" ) ) break; // skip #ifdef's inside of recv tables if ( com_token[0]=='#' ) { current = CC_ParseUntilEndOfLine( current ); continue; } // Parse recproxy line char recvproptype[ 256 ]; strcpy( recvproptype, com_token ); if ( strnicmp( recvproptype, "RecvProp", strlen( "RecvProp" ) ) ) { current = CC_ParseUntilEndOfLine( current ); continue; } if ( !strcmp( recvproptype, "RecvPropArray" ) ) { current = CC_ParseToken( current ); if ( stricmp( com_token, "(" ) ) break; current = CC_ParseToken( current ); if ( strnicmp( recvproptype, "RecvProp", strlen( "RecvProp" ) ) ) { current = CC_ParseUntilEndOfLine( current ); continue; } } current = CC_ParseToken( current ); if ( stricmp( com_token, "(" ) ) break; // Read macro or fieldname current = CC_ParseToken( current ); char varname[ 256 ]; if ( !strnicmp( com_token, "RECVINFO", strlen( "RECVINFO" ) ) ) { current = CC_ParseToken( current ); if ( stricmp( com_token, "(" ) ) break; current = CC_ParseToken( current ); } else { current = CC_ParseUntilEndOfLine( current ); continue; } strcpy( varname, com_token ); current = CC_ParseUntilEndOfLine( current ); if ( cl ) { // Look up the var CClassVariable *classVar = cl->FindVar( varname, true ); if ( classVar ) { classVar->m_bInRecvTable = true; } else { char cropped[ 256 ]; char root[ 256 ]; strcpy( cropped, varname ); while ( 1 ) { // See if varname is an embedded var char *spot = strstr( cropped, "." ); if ( spot ) { strcpy( root, cropped ); root[ spot - cropped ] = 0; strcpy( cropped, spot + 1 ); classVar = cl->FindVar( root, true ); } else { classVar = cl->FindVar( cropped, true ); break; } if ( classVar ) break; } if ( !classVar ) { vprint( 0, "class %s::%s missing, but referenced by RecvTable!!!\n", classname, varname ); } else { classVar->m_bInRecvTable = true; } } } else { vprint( 0, "class %s::%s found in RecvTable, but no such class is known!!!\n", classname, varname ); } } return current; }
char *CCodeProcessor::ParseTypeDescription( char *current, bool fIsMacroized ) { // Next token is classname then :: then variablename then braces then = then { char classname[ 256 ]; char variablename[ 256 ]; if ( !fIsMacroized ) { current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) return current; strcpy( classname, com_token ); if ( classname[0]=='*' ) return current; current = CC_ParseToken( current ); if (stricmp( com_token, ":" ) ) { return current; } current = CC_ParseToken( current ); assert( !stricmp( com_token, ":" ) ); current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) return current; strcpy( variablename, com_token ); } else { current = CC_ParseToken( current ); if (stricmp( com_token, "(" ) ) { return current; } current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) return current; strcpy( classname, com_token ); if ( classname[0]=='*' ) return current; current = CC_ParseToken( current ); if (stricmp( com_token, ")" ) ) { return current; } // It's macro-ized strcpy( variablename, "m_DataDesc" ); } if ( !fIsMacroized ) { char ch; current = CC_RawParseChar( current, "{", &ch ); assert( ch == '{' ); if ( strlen( com_token ) <= 0 ) return current; } com_ignoreinlinecomment = true; bool insidecomment = false; // Now parse typedescription line by line while ( 1 ) { current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) break; // Go to next line if ( !stricmp( com_token, "," ) ) continue; // end if ( !fIsMacroized ) { if ( !stricmp( com_token, "}" ) ) break; } else { if ( !stricmp( com_token, "END_DATADESC" ) ) break; } // skip #ifdef's inside of typedescs if ( com_token[0]=='#' ) { current = CC_ParseUntilEndOfLine( current ); continue; } if ( !stricmp( com_token, "/" ) ) { current = CC_ParseToken( current ); if ( !stricmp( com_token, "/" ) ) { // There are two styles supported. One is to have the member definition present but commented out: // DEFINE_FIELD( CMyClass, m_member, FIELD_INTEGER ), // the other is to have a comment where the first token of the comment is a member name: // m_member current = CC_ParseToken( current ); if ( !strnicmp( com_token, "DEFINE_", 7 ) ) { CC_UngetToken(); insidecomment = true; } else { char commentedvarname[ 256 ]; strcpy( commentedvarname, com_token ); CClass *cl = FindClass( classname ); if ( cl ) { if ( !cl->FindTD( commentedvarname ) ) { cl->AddTD( commentedvarname, "", "", true ); } // Mark that it has a data table cl->m_bHasSaveRestoreData = true; } current = CC_ParseUntilEndOfLine( current ); } continue; } } com_ignoreinlinecomment = false; // Parse a typedescription line char definetype[ 256 ]; strcpy( definetype, com_token ); current = CC_ParseToken( current ); if ( stricmp( com_token, "(" ) ) break; // skip classname current = CC_ParseToken( current ); if( stricmp( com_token, classname ) ) { vprint( 0, "TYPEDESCRIPTION for class %s uses offset from class %s\n", classname, com_token ); } // skip comma current = CC_ParseToken( current ); if ( !stricmp( com_token, ":" ) ) { // Scoped class name here... current = CC_ParseToken( current ); assert( !stricmp( com_token, ":" ) ); current = CC_ParseToken( current ); // skip comma current = CC_ParseToken( current ); } char varname[ 256 ]; current = CC_ParseToken( current ); strcpy( varname, com_token ); char vartype[ 256 ]; vartype[0]=0; if ( !stricmp( definetype, "DEFINE_FUNCTION" ) || !stricmp( definetype, "DEFINE_THINKFUNC" ) || !stricmp( definetype, "DEFINE_ENTITYFUNC" ) || !stricmp( definetype, "DEFINE_USEFUNC" ) || !stricmp( definetype, "DEFINE_OUTPUT" ) || !stricmp( definetype, "DEFINE_INPUTFUNC" ) ) { strcpy( vartype, "funcptr" ); } else if ( !stricmp(definetype, "DEFINE_FIELD") || !stricmp(definetype, "DEFINE_KEYFIELD") || !stricmp(definetype, "DEFINE_KEYFIELD_NOT_SAVED") || !stricmp(definetype, "DEFINE_UTLVECTOR") || !stricmp(definetype, "DEFINE_GLOBAL_FIELD") || !stricmp(definetype, "DEFINE_GLOBAL_KEYFIELD") || !stricmp(definetype, "DEFINE_INPUT") || !stricmp(definetype, "DEFINE_AUTO_ARRAY") || !stricmp(definetype, "DEFINE_AUTO_ARRAY2D") || !stricmp(definetype, "DEFINE_ARRAY") ) { // skip comma current = CC_ParseToken( current ); if (!strcmp( com_token, "[" )) { // Read array... current = CC_ParseToken( current ); strcat( varname, "[" ); strcat( varname, com_token ); current = CC_ParseToken( current ); assert (!strcmp( com_token, "]" )); strcat( varname, "]" ); // skip comma current = CC_ParseToken( current ); } current = CC_ParseToken( current ); strcpy( vartype, com_token ); } // Jump to end of definition int nParenCount = 1; do { current = CC_ParseToken( current ); if ( strlen( com_token ) <= 0 ) break; if ( !stricmp( com_token, "(" ) ) { ++nParenCount; } else if ( !stricmp( com_token, ")" ) ) { if ( --nParenCount == 0 ) { break; } } } while ( 1 ); // vprint( 2, "%s%s::%s %s %s %s\n", // insidecomment ? "// " : "", // classname, variablename, // definetype, varname, vartype ); CClass *cl = FindClass( classname ); if ( cl ) { if ( strcmp( vartype, "funcptr" ) && cl->FindTD( varname ) ) { vprint( 0, "class %s::%s already has typedescription entry for field %s\n", classname, variablename, varname ); } else { cl->AddTD( varname, vartype, definetype, insidecomment ); } // Mark that it has a data table cl->m_bHasSaveRestoreData = true; } insidecomment = false; com_ignoreinlinecomment = true; } com_ignoreinlinecomment = false; return current; }
void CCodeProcessor::ProcessModule( bool forcequiet, int depth, int& maxdepth, int& numheaders, int& skippedfiles, const char *srcroot, const char *baseroot, const char *root, const char *module ) { char filename[ 256 ]; if ( depth > maxdepth ) { maxdepth = depth; } int filelength; char *buffer = NULL; // Always skip these particular modules/headers if ( SkipFile( module ) ) { CODE_MODULE module; module.skipped = true; m_Modules.Insert( filename, module ); skippedfiles++; return; } if ( !LoadFile( &buffer, filename, module, forcequiet, depth, filelength, numheaders, skippedfiles, srcroot, root, baseroot ) ) { CODE_MODULE module; module.skipped = true; m_Modules.Insert( filename, module ); skippedfiles++; return; } assert( buffer ); m_nBytesProcessed += filelength; CODE_MODULE m; m.skipped = false; m_Modules.Insert( filename, m ); if ( !forcequiet ) { strcpy( m_szCurrentCPP, filename ); } AddHeader( depth, filename, m_szCurrentCPP ); bool onclient = !strnicmp( m_szBaseEntityClass, "C_", 2 ) ? true : false; // Parse tokens looking for #include directives or class starts char *current = buffer; current = CC_ParseToken( current ); while ( 1 ) { // No more tokens if ( !current ) break; if ( !stricmp( com_token, "#include" ) ) { current = CC_ParseToken( current ); if ( strlen( com_token ) > 0 && com_token[ 0 ] != '<' ) { //vprint( "#include %s\n", com_token ); m_nHeadersProcessed++; numheaders++; ProcessModule( true, depth + 1, maxdepth, numheaders, skippedfiles, srcroot, baseroot, root, com_token ); } } else if ( !stricmp( com_token, "class" ) || !stricmp( com_token, "struct" ) ) { current = CC_ParseToken( current ); if ( strlen( com_token ) > 0 ) { //vprint( depth, "class %s\n", com_token ); CClass *cl = AddClass( com_token ); // Now see if there's a base class current = CC_ParseToken( current ); if ( !stricmp( com_token, ":" ) ) { // Parse out public and then classname an current = CC_ParseToken( current ); if ( !stricmp( com_token, "public" ) ) { current = CC_ParseToken( current ); if ( strlen( com_token ) > 0 ) { cl->SetBaseClass( com_token ); do { current = CC_ParseToken( current ); } while ( strlen( com_token ) && stricmp( com_token, "{" ) ); if ( !stricmp( com_token, "{" ) ) { current = cl->ParseClassDeclaration( current ); } } } } else if ( !stricmp( com_token, "{" ) ) { current = cl->ParseClassDeclaration( current ); } } } else if ( !strnicmp( com_token, "PREDICTABLE_CLASS", strlen( "PREDICTABLE_CLASS" ) ) ) { char prefix[ 32 ]; prefix[ 0 ] = 0; int type = 0; int bases = 1; int usebase = 0; if ( !stricmp( com_token, "PREDICTABLE_CLASS_ALIASED" ) ) { type = 2; bases = 2; if ( onclient ) { strcpy( prefix, "C_" ); } else { strcpy( prefix, "C" ); usebase = 1; } } else if ( !stricmp( com_token, "PREDICTABLE_CLASS_SHARED" ) ) { type = 1; bases = 1; } else if ( !stricmp( com_token, "PREDICTABLE_CLASS" ) ) { type = 0; bases = 1; if ( onclient ) { strcpy( prefix, "C_" ); } else { strcpy( prefix, "C" ); } } else if ( !stricmp( com_token, "PREDICTABLE_CLASS_ALIASED_PREFIXED" ) ) { // Nothing } else { vprint( 0, "PREDICTABLE_CLASS of unknown type!!! %s\n", com_token ); } // parse the ( current = CC_ParseToken( current ); if ( !strcmp( com_token, "(" ) ) { // Now the classname current = CC_ParseToken( current ); if ( strlen( com_token ) > 0 ) { //vprint( depth, "class %s\n", com_token ); CClass *cl = AddClass( com_token ); // Now see if there's a base class current = CC_ParseToken( current ); if ( !stricmp( com_token, "," ) ) { // Parse out public and then classname an current = CC_ParseToken( current ); if ( strlen( com_token ) > 0 ) { char basename[ 256 ]; sprintf( basename, "%s%s", prefix, com_token ); bool valid = true; if ( bases == 2 ) { valid = false; current = CC_ParseToken( current ); if ( !stricmp( com_token, "," ) ) { current = CC_ParseToken( current ); if ( strlen( com_token ) > 0 ) { valid = true; if ( usebase == 1 ) { sprintf( basename, "%s%s", prefix, com_token ); } } } } if ( valid ) { cl->SetBaseClass( basename ); strcpy( cl->m_szTypedefBaseClass, basename ); } do { current = CC_ParseToken( current ); } while ( strlen( com_token ) && stricmp( com_token, ")" ) ); if ( !stricmp( com_token, ")" ) ) { current = cl->ParseClassDeclaration( current ); } } } else if ( !stricmp( com_token, ")" ) ) { current = cl->ParseClassDeclaration( current ); } } } } else if ( !strcmp( com_token, "TYPEDESCRIPTION" ) || !strcmp( com_token, "typedescription_t" ) ) { current = ParseTypeDescription( current, false ); } else if ( !strcmp( com_token, "BEGIN_DATADESC" ) || !strcmp( com_token, "BEGIN_DATADESC_NO_BASE" ) || !strcmp( com_token, "BEGIN_SIMPLE_DATADESC" ) ) { current = ParseTypeDescription( current, true ); } else if ( !strcmp( com_token, "BEGIN_PREDICTION_DATA" ) || !strcmp( com_token, "BEGIN_EMBEDDED_PREDDESC" ) ) { current = ParsePredictionTypeDescription( current ); } else if ( !strcmp( com_token, "BEGIN_RECV_TABLE" ) || !strcmp( com_token, "BEGIN_RECV_TABLE_NOBASE" ) || !strcmp( com_token, "IMPLEMENT_CLIENTCLASS_DT" ) || !strcmp( com_token, "IMPLEMENT_CLIENTCLASS_DT_NOBASE" ) ) { current = ParseReceiveTable( current ); } else if ( !strcmp( com_token, "IMPLEMENT_PREDICTABLE_NODATA" ) ) { current = CC_ParseToken( current ); if ( !strcmp( com_token, "(" ) ) { current = CC_ParseToken( current ); CClass *cl = FindClass( com_token ); if ( cl ) { if ( cl->m_bHasPredictionData ) { if ( !forcequiet ) { vprint( 0, "Class %s declared predictable and implemented with IMPLEMENT_PREDICTABLE_NODATA in typedescription\n", cl->m_szName ); } cl->m_bHasPredictionData = false; } } current = CC_ParseToken( current ); } } current = CC_ParseToken( current ); } COM_FreeFile( (unsigned char *)buffer ); if ( !forcequiet && !GetQuiet() ) { vprint( 0, " %s: headers (%i game / %i total)", (char *)&filename[ m_nOffset ], numheaders - skippedfiles, numheaders ); if ( maxdepth > 1 ) { vprint( 0, ", depth %i", maxdepth ); } vprint( 0, "\n" ); } m_nLinesOfCode += linesprocessed; linesprocessed = 0; }
void CCodeProcessor::ProcessModule( bool forcequiet, int depth, int& maxdepth, int& numheaders, int& skippedfiles, const char *baseroot, const char *root, const char *module ) { char filename[ 256 ]; bool checkroot = false; if ( depth > maxdepth ) { maxdepth = depth; } // Load the base module sprintf( filename, "%s\\%s", root, module ); strlwr( filename ); bool firstheader = true; retry: // Check module list for ( int i = 0; i < m_nModuleCount; i++ ) { if ( !stricmp( m_Modules[ i ].name, filename ) ) { if ( forcequiet ) { m_nHeadersProcessed++; numheaders++; if ( m_Modules[ i ].skipped ) { skippedfiles++; } } AddHeader( depth, filename, m_szCurrentCPP ); return; } } int filelength; char *buffer = (char *)COM_LoadFile( filename, &filelength ); if ( !buffer ) { if ( !checkroot ) { checkroot = true; // Load the base module sprintf( filename, "%s\\%s", baseroot, module ); goto retry; } m_Modules[ m_nModuleCount ].skipped = true; strcpy( m_Modules[ m_nModuleCount++ ].name, filename ); skippedfiles++; return; } m_nBytesProcessed += filelength; m_Modules[ m_nModuleCount ].skipped = false; strcpy( m_Modules[ m_nModuleCount++ ].name, filename ); bool readonly = false; bool madechanges = false; CreateBackup( filename, readonly ); if ( !forcequiet ) { strcpy( m_szCurrentCPP, filename ); vprint( 0, "- %s\n", (char *)&filename[ m_nOffset ] ); } // Parse tokens looking for #include directives or class starts char *current = buffer; char *startofline; current = CC_ParseToken( current ); while ( current ) { // No more tokens if ( strlen( com_token ) <= 0 ) break; if ( !stricmp( com_token, "#include" ) ) { startofline = current - strlen( "#include" ); current = CC_ParseToken( current ); if ( strlen( com_token ) > 0) { vprint( 1, "#include %s", com_token ); m_nHeadersProcessed++; numheaders++; AddHeader( depth, filename, m_szCurrentCPP ); bool dobuild = true; if ( firstheader ) { if ( !stricmp( com_token, "cbase.h" ) ) { dobuild = false; } if ( !TryBuild( baseroot, filename, (unsigned char *)buffer, filelength ) ) { // build is broken, stop assert( 0 ); } } firstheader = false; if ( dobuild ) { // Try removing the header and compiling char saveinfo[2]; memcpy( saveinfo, startofline, 2 ); startofline[ 0 ] = '/'; startofline[ 1 ] = '/'; if ( TryBuild( baseroot, filename, (unsigned char *)buffer, filelength ) ) { vprint( 0, ", unnecessary\n" ); madechanges = true; } else { // Restore line memcpy( startofline, saveinfo, 2 ); vprint( 0, "\n" ); } } else { vprint( 0, "\n" ); } } } current = CC_ParseToken( current ); } // Save out last set of changes { FILE *fp; fp = fopen( filename, "wb" ); if ( fp ) { fwrite( buffer, filelength, 1, fp ); fclose( fp ); } } COM_FreeFile( (unsigned char *)buffer ); if ( !madechanges ) { RestoreBackup( filename, readonly ); } if ( !forcequiet && !GetQuiet() ) { vprint( 0, " %s: headers (%i)", (char *)&filename[ m_nOffset ], numheaders ); if ( maxdepth > 1 ) { vprint( 0, ", depth %i", maxdepth ); } vprint( 0, "\n" ); } m_nLinesOfCode += linesprocessed; linesprocessed = 0; }