Logo Search packages:      
Sourcecode: aime version File versions  Download package

memchk.cpp

/**********************************************************************
 ** Memchk - a group of functions used as a memory tool, designed to
 **          help identify large memory leaks in the code
 **
 **
 **    
 ** Last reviewed: 
 **
 **
 ** Copyright (C) 2000 George Noel (Slate)
 **
 **   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 2 of the 
 **   License, or 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 (in the docs dir); if not, write to the Free
 **   Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 **
 **********************************************************************/

#ifndef MEMCHK_C
#define MEMCHK_C

#include "config.h"
#include "sysdep.h"
#include "mudtypes.h"
#include "mudobject.h"
#include "memchk.h"
#include "newfuncts.h"

mem_unit *mem_list = NULL;
int      freeze = 0;

/***********************************************************************
 ** add_mem_unit - adds or increments a memory unit in the linked list
 **
 ** Parameters: unit_name - the name of the variable we add or increment
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int add_mem_unit(char *unit_name)
{
   return add_mem_unit(unit_name, 1);
}


/***********************************************************************
 ** add_mem_unit - adds or increments a memory unit in the linked list
 **
 ** Parameters: unit_name - the name of the variable we add or increment
 **             num_units - the number of units to add
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int add_mem_unit(char *unit_name, int num_units)
{
   return add_mem_unit(unit_name, num_units, Obj_Type);
}


/***********************************************************************
 ** add_mem_unit - adds or increments a memory unit in the linked list
 **
 ** Parameters: unit_name - the name of the variable we add or increment
 **             num_units - the number of units to increment
 **             the_type - the type of memory unit to add
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int add_mem_unit(char *unit_name, int num_units, mem_type the_type)
{
   mem_unit *tmp_mem;
   mem_unit *prev_mem = NULL;
   mem_unit *swap_mem = NULL;

   if (unit_name == NULL)
      return -1;

   if (freeze)
   {
      return 0;
   }

   tmp_mem = mem_list;
   while ((tmp_mem != NULL) && (STRCASECMP(tmp_mem->mem_name, unit_name)))
   {
      swap_mem = prev_mem;
      prev_mem = tmp_mem;
      tmp_mem = tmp_mem->next_mem;
   }

   /* if we dont find it, create a new one */
   if (tmp_mem == NULL)
   {
      mem_unit *new_mem;

      new_mem = new mem_unit;

      /* we don't use the newfuncts new_char funct here to avoid recursive
         loops.  Just have to make sure this is really tight */
      new_mem->mem_name = new char[strlen(unit_name)+2];
      strcpy(new_mem->mem_name, unit_name);
      new_mem->count = num_units;
      new_mem->next_mem = NULL;
      new_mem->the_type = the_type;

      if (prev_mem == NULL)
         mem_list = new_mem;
      else
          prev_mem->next_mem = new_mem;
   }

   /* if we do find it, up the current number and move it up once in the
      list to ensure the most frequent ones are at the top for speed */
   else
   {
      if (prev_mem != NULL)
      {
         prev_mem->next_mem = tmp_mem->next_mem;
         tmp_mem->next_mem = prev_mem;
         if (swap_mem == NULL)
       {
            mem_list = tmp_mem;
         }
         else
            swap_mem->next_mem = tmp_mem;
      }
      tmp_mem->count += num_units;
   }
   return 1;
}

/***********************************************************************
 ** del_mem_unit - deletes or decrements a memory unit in the linked list
 **
 ** Parameters: unit_name - the name of the variable we del or decrement
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int del_mem_unit(char *unit_name)
{
   return del_mem_unit(unit_name, 1);
}


/***********************************************************************
 ** del_mem_unit - deletes or decrements a memory unit in the linked list
 **
 ** Parameters: unit_name - the name of the variable we del or decrement
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int del_mem_unit(char *unit_name, int num_units)
{
   mem_unit *tmp_mem;
   mem_unit *prev_mem = NULL;

   if (unit_name == NULL)
      return -1;

   if (freeze)
      return 0;

   tmp_mem = mem_list;
   while ((tmp_mem != NULL) && (STRCASECMP(tmp_mem->mem_name, unit_name)))
   {
      prev_mem = tmp_mem;
      tmp_mem = tmp_mem->next_mem;
   }

   /* if we dont find it, return -1 */
   if (tmp_mem == NULL)
      return -1;

   tmp_mem->count -= num_units;
 
   if (tmp_mem->count == 0)
   {
      if (prev_mem == NULL)
      {
         mem_list = tmp_mem->next_mem;
      }
      else
         prev_mem->next_mem = tmp_mem->next_mem;

      delete tmp_mem->mem_name;
      delete tmp_mem;
   }
   return 1;
}

/***********************************************************************
 ** show_mem - displays the list of memory used to the user
 **
 ** Parameters: the_player - the player to send the list to
 **
 ** Returns: 1 for success, -1 for failure
 **
 ***********************************************************************/

int show_mem(Player *the_player)
{
   mem_unit *tmp_mem;
   char     *tabs;

 //  if (the_player == NULL)
  //    return -1;

   tmp_mem = mem_list;
   the_player->send_plr("\n");

   freeze = 1;  // stop from writing to the list while we are reading it

   /* first display the object memory units */
   the_player->send_plr("&+GStructs/Classes in Memory&*\n");
   the_player->send_plr("&+B-----------------------------&*\n\n");

   while (tmp_mem != NULL)
   {
      if (tmp_mem->the_type == Obj_Type)
      {
         if (strlen(tmp_mem->mem_name) > 7)
            tabs = "\t";
         else
            tabs = "\t\t";

         the_player->send_plr("%s%s%d\n", tmp_mem->mem_name, tabs, 
                                                         tmp_mem->count);
      }
      tmp_mem = tmp_mem->next_mem;
   }


   /* next display the file descriptors */
   tmp_mem = mem_list;
   the_player->send_plr("&+G\n\nFile Descriptors Open&*\n");
   the_player->send_plr("&+B-----------------------------&*\n\n");

   while (tmp_mem != NULL)
   {
      if (tmp_mem->the_type == File_Desc)
      {
         if (strlen(tmp_mem->mem_name) > 7)
            tabs = "\t";
         else
            tabs = "\t\t";

         the_player->send_plr("%s%s%d\n", tmp_mem->mem_name, tabs, 
                                                         tmp_mem->count);
      }
      tmp_mem = tmp_mem->next_mem;
   }
   freeze = 0;
   return 1;
}

/***********************************************************************
 ** xfopen - wrapper function for the fopen, keeps track of file
 **          descriptors open so we can ensure they get closed
 **          properly
 **
 ** Parameters: the_filename - the filename to open
 **             mode - the mode to open the file in
 **             desc - one-word description of the file descriptor
 **             
 **
 ** Returns: pointer to a FILE struct
 **
 ***********************************************************************/

FILE *xfopen(char *the_filename, char *mode, char *desc)
{
   FILE *tmp_file = NULL;

   tmp_file = fopen(the_filename, mode);

#ifdef DEBUG_MEM   
   if (tmp_file != NULL)
   {
      add_mem_unit(desc, 1, File_Desc);
   }
#endif

   desc = NULL;  // eliminate compile errors

   return tmp_file;
}

/***********************************************************************
 ** xfclose - wrapper function for the fclose, ensures we record that this
 **           specific file descriptor (hopefully opened with xfopen or
 **           this is pointless) was closed.
 **
 ** Parameters: the_file - the file descriptor to close
 **             desc - one-word description of the file descriptor
 **             
 ** Returns: whatever fclose returns
 **
 ***********************************************************************/

int xfclose(FILE *the_file, char *desc)
{
   if (the_file == NULL)
   {
      printf("Error, tried to close a closed file descriptor!\n");
      RAISE(1);
      return -1;
   }
 
#ifdef DEBUG_MEM
   if (del_mem_unit(desc) == -1)
      printf("Error, file descriptor '%s' was closed, but not opened with\n"
             "the xfopen command.\n", desc);
#endif   
   desc = NULL;  // eliminate compiler errors

   return fclose(the_file);
}


#endif





Generated by  Doxygen 1.6.0   Back to index