// *Buffer Enhancement:  This can save you LOTS of time tracking bugs. * //
// *This is one of many little enhancements to my buffer system        * //
// * I hope you Enjoy this :)                                          * //

// *This will require you to replace some of your existing code, or    * //
// *Modify it slightly.                                                * //

// *This contains afew things from my mud that are used by me to find  * //
// *bugs.                                                              * //

// * Enjoy :)    -- Dazzle of Sandstorm: The Mages Sanctuary           * //

in recycle.c add the following at the top.
BUFFER *buffer_list;
int top_buffer;



now find the function BUFFER *new_buf()

Replace the top part with the following, before it actauly enters the
code for the new_buf, and replace it with this.

BUFFER *__new_buf(const char *file, const char *function, int line)


Now inside of the __new_buf function, after buffer->size = get_size(BASE_BUF);

put in the following.

    /*For debugging purposes*/
    buffer->file    = str_dup(file);
    buffer->function= str_dup(function);
    buffer->line    = line;


now, after the buffer->string portion is created, before VALIDATE(buffer); put
the following.


    top_buffer++;
    LINK_SINGLE(buffer, next, buffer_list);



Now, in free_buf, put the following;

  free_string(buffer->file);
  free_string(buffer->function);
  top_buffer--;
  UNLINK_SINGLE(buffer, next, BUFFER, buffer_list);


now after add_buf, add this.
void BufPrintf ( BUFFER * buffer, char * fmt, ... )
{
    char buf[MSL];
    va_list args;

    va_start ( args, fmt );
    vsnprintf ( buf, LBUF, fmt, args );
    va_end ( args );

    add_buf ( buffer, buf );
    return;
}

now in act_wiz.c  throw this in there.

/*Find and display where buffers are stuck open (MUAHAHAHA!)
 *Great Debugging tool, by Dazzle(Darien) of Sandstorm
 */
MUDCMD(do_trackbuffer)
{
	BUFFER *output = new_buf();
	BUFFER *count, *count_next;
	int counter =0;

	for(count = buffer_list; count; count = count_next)
	{
		count_next = count->next;
		if(count != output)
			BufPrintf(output,"Buffer Found:File: %s, Function: %s, Line: %d\n\r",count->file, count->function, count->line);
		else
			BufPrintf(output,"Buffer Found:File: Called by this function! (Ignore!)\n\r");
		counter++;
	}

	BufPrintf(output,"%d buffers were found open.\n\r",counter);
	page_to_char(buf_string(output), ch);
	free_buf(output);
	return;
}


in recycle.h, replace your BUFFER *new_buf() crap with this.

/* buffer procedures */
BUFFER	*__new_buf args( (const char *file, const char *function, int line) );
#define new_buf() __new_buf(__FILE__, __FUNCTION__, __LINE__)
void BufPrintf args(( BUFFER * buffer, char * fmt, ... ));


merc.h or externs.h, which-ever one you have, for external variables, add

extern BUFFER *buffer_list;
extern int top_buffer;


in interp.h add
DECLARE_DO_FUN(do_trackbuffer);

in interp.c, add a call for the do_trackbuffer command.

// *Thanks goto markanth for the BufPrintf function, and for the singly linked code.* // 
// * LINK_SINGLE/UNLINK_SINGLE are awesome functions for handling your singly linked* //
// * lists, i use them for all of mine, courtesy of the firstmud mudbase.           * //
#define LINK_SINGLE(pdata,pnext,list) \
do \
{ \
		pdata->pnext = list; \
		list = pdata; \
} \
while (0)

#define UNLINK_SINGLE(pdata,pnext,type,list) \
do                                          \
{                                          \
	if (list == pdata)                      \
	{                                       \
		list = pdata->pnext;                 \
	}                                       \
	else                                    \
	{                                       \
		type *prev;                         \
		for (prev = list; prev != NULL; prev = prev->pnext) \
		{                                   \
			if (prev->pnext == pdata)        \
			{                               \
				prev->pnext = pdata->pnext;   \
				break;                      \
			}                               \
		}                                   \
		if (prev == NULL)                   \
		{                                   \
			nlogf( #pdata " not found in " #list "."); \
		}                                   \
	}                                       \
} while(0)


Just a heads up, the trackbuffer command will display any open buffer.
So if you have 20 players on your mud, you will have 21 buffers open, no more, no less.
Reason for this is because each player in their pc_data, has new_buf called, so there is 20.
And the function itself, uses 1 buffer, and it notes that.  If you have 1 player online, and 20
buffers open, you have a problem ;)

I have found that MANY snippets out there, do not properly close the buffers when they are done,
and then people wonder why they are crashing, or using up sooo much memory, well, the fact is,
the data hasn't been free'd, so here is a GREAT way to track it down.

I would point fingers at afew of the snippets, but i don't feel like having the owners of them
yell at me again (ya, i talked with them about it, and they said they didn't give a flying f*ck)
so ya, this will atleast allow you to have alittle more faith in new snippets, because if they
use buffers, and your lazy and don't go over the code before you install it to find possible bugs,
then this will most definetly aid-you.


Anyways, thats just my opinion, hope you enjoy it.






