void ParseMemoryLeakFile ( char *_inputFilename, char *_outputFilename ) { // // Start up // BTree <int> combined; BTree <int> frequency; int unrecognised = 0; // // Open the file and start parsing // ifstream memoryfile ( _inputFilename ); while ( !memoryfile.eof () ) { char thisline [256]; memoryfile.getline ( thisline, 256 ); if ( !strncmp ( thisline, " Data:", 6 ) == 0 && // This line is a data line - useless to us strchr ( thisline, ':' ) ) { // This line does not have a source file location - useless to us // Get the size char *lastcomma = strrchr ( thisline, ',' ); char *ssize = lastcomma+2; int size; char unused [32]; sscanf ( ssize, "%d %s", &size, unused ); // Get the source file name char *sourcelocation = thisline; char *colon = strrchr ( thisline, ':' ); *(colon-1) = '\x0'; char *lowercasesourcelocation = LowerCaseString ( sourcelocation ); // Put the result into our BTree BTree <int> *btree = combined.LookupTree ( lowercasesourcelocation ); if ( btree ) ((int) btree->data) += size; else combined.PutData ( lowercasesourcelocation, size ); BTree <int> *freq = frequency.LookupTree ( lowercasesourcelocation ); if ( freq ) ((int) freq->data) ++; else frequency.PutData ( lowercasesourcelocation, 1 ); delete lowercasesourcelocation; } else { char *lastcomma = strrchr ( thisline, ',' ); if ( lastcomma ) { char *ssize = lastcomma+2; int size; char unused [32]; if( sscanf ( ssize, "%d %s", &size, unused ) == 2 ) unrecognised += size; } } } memoryfile.close (); // // Sort the results into a list // DArray <int> *sizes = combined.ConvertToDArray (); DArray <char *> *sources = combined.ConvertIndexToDArray (); LList <char *> sorted; int totalsize = 0; for ( int i = 0; i < sources->Size (); ++i ) { char *newsource = sources->GetData (i); int newsize = sizes->GetData (i); totalsize += newsize; bool inserted = false; for ( int j = 0; j < sorted.Size (); ++j ) { char *existingsource = sorted.GetData (j); int existingsize = combined.GetData ( existingsource ); if ( newsize <= existingsize ) { sorted.PutDataAtIndex ( newsource, j ); inserted = true; break; } } if ( !inserted ) sorted.PutDataAtEnd ( newsource ); } // // Open the output file // FILE *output = fopen( _outputFilename, "wt" ); // // Print out our sorted list // fprintf ( output, "Total recognised memory leaks : %d Kbytes\n", int(totalsize/1024) ); fprintf ( output, "Total unrecognised memory leaks : %d Kbytes\n\n", int(unrecognised/1024) ); for ( int k = sorted.Size () - 1; k >= 0; --k ) { char *source = sorted.GetData (k); int size = combined.GetData ( source ); int freq = frequency.GetData ( source ); if( size > 2048 ) { fprintf ( output, "%-95s (%d Kbytes in %d leaks)\n", source, int(size/1024), freq ); } else { fprintf ( output, "%-95s (%d bytes in %d leaks)\n", source, size, freq ); } } // // Clear up fclose( output ); delete sources; delete sizes; }
void SWInterface::ToggleSubMenu ( int softwareTYPE, int x, int y ) { if ( !IsVisibleSubMenu ( softwareTYPE ) ) { // Create a list of all software in memory LList <char *> software; // Bit of a hack - think about this LList <float> versions; DataBank *db = &(game->GetWorld ()->GetPlayer ()->gateway.databank); for ( int di = 0; di < db->GetDataSize (); ++di ) { if ( db->GetDataFile (di) && db->GetDataFile (di)->TYPE == DATATYPE_PROGRAM && db->GetDataFile (di)->softwareTYPE == softwareTYPE ) { // This sofware is the correct type. Add it into the list if it isn't already there, // or if its version is higher than any existing program of the same name // First try to find a software item of the same name int existingindex = -1; for ( int si = 0; si < software.Size (); ++si ) { if ( strcmp ( software.GetData (si), db->GetDataFile (di)->title ) == 0 ) { existingindex = si; break; } } // If it already exists, add this item in only if it has a higher version number if ( existingindex == -1 ) { software.PutData ( db->GetDataFile (di)->title ); versions.PutData ( db->GetDataFile (di)->version ); } if ( existingindex != -1 && db->GetDataFile (di)->version > versions.GetData (existingindex) ) { software.RemoveData ( existingindex ); versions.RemoveData ( existingindex ); software.PutDataAtIndex ( db->GetDataFile (di)->title, existingindex ); versions.PutDataAtIndex ( db->GetDataFile (di)->version, existingindex ); } } } int timesplit = 500; if ( software.Size () > 0 ) timesplit /= software.Size (); // Ensures total time = 500ms for ( int si = 0; si < software.Size (); ++si ) { char caption [128], tooltip [128], name [128]; UplinkSnprintf ( caption, sizeof ( caption ), "%s v%1.1f", software.GetData (si), versions.GetData (si) ); UplinkStrncpy ( tooltip, "Runs this software application", sizeof ( tooltip ) ); UplinkSnprintf ( name, sizeof ( name ), "hud_software %d", si ); EclRegisterButton ( x, y, 140, 15, caption, tooltip, name ); EclRegisterButtonCallbacks ( name, SoftwareDraw, SoftwareClick, button_click, SoftwareHighlight ); EclRegisterMovement ( name, x, y - si * 17, si * timesplit ); } currentsubmenu = softwareTYPE; SgPlaySound ( RsArchiveFileOpen ( "sounds/softwaremenu.wav" ), "sounds/softwaremenu.wav", false ); } else { // Remove the software menu // We don't know how many entries there could be, so keep deleting until they run out int i = 0; char name [32]; UplinkSnprintf ( name, sizeof ( name ), "hud_software %d", i ); while ( EclGetButton ( name ) != NULL ) { EclRemoveButton ( name ); ++i; UplinkSnprintf ( name, sizeof ( name ), "hud_software %d", i ); } // Redraw the button that was selected char bname [32]; UplinkSnprintf ( bname, sizeof ( bname ), "hud_swmenu %d", currentsubmenu ); EclDirtyButton ( bname ); currentsubmenu = SOFTWARETYPE_NONE; } }