TinyMAZE/
TinyMAZE/config/
TinyMAZE/doc/
TinyMAZE/run/msgs/
TinyMAZE/src/
TinyMAZE/src/db/
TinyMAZE/src/ident/
TinyMAZE/src/io/
TinyMAZE/src/prog/
TinyMAZE/src/softcode/
TinyMAZE/src/util/
                               The TinyMAZEv2 Stack
                               --------------------

	TinyMAZEv2 has what I called a stack. It's not really a stack at
all, but a simple memory management system. You can use the stack in a
couple of different ways: 1) For temporary memory allocation. 2) For
temporary and permanent memory allocation.

	Some of you might be wondering what I mean by temporary and
permanent. A temporary memory allocation is something that you only need
for a very short period of time. At the of a user command and at the end
of the dispatch() call, all temporary allocations are freed.

	All of the memory allocation done in the TinyMAZEv2 server should
be done via the stack system. Otherwise things might get quite messy.

Here are the stack allocation calls:
  stack_alloc(unsigned long size, bool permanent, bool clear);
  stack_realloc(void *ptr, unsigned long size);
  stack_realloc_tmp(void *ptr, unsigned long size);
  stack_free(void *ptr);
  stack_free_tmp(void *ptr);
  stack_string_alloc(char *str, bool permanent);
  stack_string_realloc(void *ptr, char *str);
  stack_string_realloc_tmp(void *ptr, char *str);

Example:
	Let's say you have a function that returns every other letter of
the string passed to it. It would look like this:

char *every_other(char *str)
{
  static char buf[1024];
  char *p, *b;

  for(b = buf, p = str;*p;p++)
    if(!((p-str) % 2))
      *b++ = *p;
  *b = '\0';

  return(buf);
}

	The static declaration for buf is necessary because a dynamic
buffer is freed as soon as the function ends and you might end up
returning garbage to the calling function. However, with the stack you can
eliminate the need for the static declaration with a temporary allocation
call. Like this:

char *every_other(char *str)
{
  char buf[1024];
  char *p, *b;

  for(b = buf, p = str;*p;p++)
    if(!((p-str) % 2))
      *b++ = *p;
  *b = '\0';

  return(stack_string_alloc(buf, 0));
}

	The memory allocated in this example will automatically be freed
by the server.

	At the top of the file maze/stack.c there is a #define
STACK_USAGE. There is a comment right above it explaining what different
settings do.

	If you opt to use the stack for only temporary memory management,
the server will use normal memory allocation calls when you use the stack
function calls instead of reserving memory on the stack for permanent
memory allocation.

An indepth look at each of the stack function calls is in order:

  void *stack_alloc(unsigned long size, int permanent, int clear);

	Returns a pointer to reserved memory of 'size' bytes. 'permanent'
may be 1 or 0. If it is 1, the reserved memory will not be automatically
freed by the server and must be freed manually. If set to 0, the memory
will be freed at the end of the user command or at the end of the
dispatch() function call that happens every second. 'clear' may be 1 or
0. If set 1, the memory will be cleared (filled with 0's) making it act
like a calloc() call instead of malloc(). If set to 0, the reserved memory
will be left untouched.

  void *stack_realloc(void *ptr, unsigned long size);

	Returns a pointer to memory of 'size' bytes. 'ptr' must be a valid
memory address returned by a previous permanent stack allocation
function. The memory at 'ptr' will be resized to 'size' bytes. The
contents of 'ptr' will be left untouched. If 'size' is 0, this function
acts like a call to stack_free().

  void *stack_realloc_tmp(void *ptr, unsigned long size);

	This works the same as stack_realloc() except it works on
temporary allocations as well.

  void stack_free(void *ptr);

	Frees (unallocates) a chunk of memory previously reserved by
another stack allocation call. If you want to free a temporary allocation
you must use stack_free_tmp().

  void stack_free_tmp(void *ptr);

	This works the same way as stack_free() except it works on
temporary allocations as well.

  char *stack_string_alloc(char *str, int permanent);

	Returns a pointer to memory of strlen(str)+1 bytes. The returned
pointer is filled with the contents of 'str', acting like a
strdup() call. 'permanent' may be 1 or 0. If it is 1 the memory reserved
will not be automatically freed by the server and must be freed manually
with a stack_free() call.

  char *stack_string_realloc(void *ptr, char *str);

	This function acts like stack_realloc() except that it fills the
returned pointer with the contents of 'str'.

  char *stack_string_realloc_tmp(void *ptr, char *str);
	This works the same as stack_string_realloc() except it works on
temporary allocations as well.

	The stack system may be used as a memory leak detection
system. When the system shuts down it dumps a report of the stack to the
file 'run/stack_report'. For this to work properly you must have the
#define STACK_USAGE at the top of 'maze/stack.c' set to 2 so the server
uses the stack for permanent memory allocation.