/*
Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
*/
/* configure all options BEFORE including system stuff. */
#include "config.h"
#include "mud.h"
/*
routines that handle copying stuff in memory, and other main
memory allocation shenanigans.
*/
/*
#define ALLOC_DEBUG
*/
/*
temporary data is managed by keeping a list of allocated stuff, which
can be traversed and freed. this is not too terribly efficient, but
is not a load-bearing section of code.
*/
struct tmplist {
struct tmplist *next;
mall_t dat;
};
/* list of currently active temporaries */
static struct tmplist *tmpl;
/* list of temp list structures that have been freed and stacked */
static struct tmplist *freetmpl;
/* just like malloc() but keep track of the storage */
mall_t tmpalloc (size_t siz)
{
struct tmplist *lp;
if (freetmpl != (struct tmplist *) 0) {
lp = freetmpl;
#ifdef ALLOC_DEBUG
printf ("take holder %d from tmp holder list\n", lp);
#endif
freetmpl = freetmpl->next;
} else {
if ((lp = (struct tmplist *) malloc (sizeof (struct tmplist))) == 0)
return ((mall_t) 0);
}
lp->dat = malloc ((unsigned) siz);
/* add to the chain */
lp->next = tmpl;
tmpl = lp;
#ifdef ALLOC_DEBUG
printf ("tmpalloc %d bytes at %d (holder is %d)\n", siz, lp->dat, lp);
#endif
return (lp->dat);
}
/*
put something on the temp list to free later.
this results in what is basically a deferred free() - executed
at the end of each machine run.
*/
void deferfree (mall_t p)
{
struct tmplist *lp;
if (freetmpl != (struct tmplist *) 0) {
lp = freetmpl;
#ifdef ALLOC_DEBUG
printf ("take holder %d from tmp holder list\n", lp);
#endif
freetmpl = freetmpl->next;
} else {
if ((lp = (struct tmplist *) malloc (sizeof (struct tmplist))) == 0) {
#ifdef ALLOC_DEBUG
printf ("deferfree can't allocate holder, leaks memory\n");
#endif
return;
}
}
lp->dat = p;
lp->next = tmpl;
tmpl = lp;
#ifdef ALLOC_DEBUG
printf ("tmpputonfree ? bytes at %d (holder is %d)\n", lp->dat, lp);
#endif
}
/* free all the temporaries */
void tmp_sync ()
{
register struct tmplist *lp = tmpl;
register struct tmplist *np;
if (tmpl == (struct tmplist *) 0)
return;
while (lp != (struct tmplist *) 0) {
if (lp->dat != 0)
(void) free (lp->dat);
#ifdef ALLOC_DEBUG
printf ("tmpsync at %d (holder is %d)\n", lp->dat, lp);
#endif
np = lp->next;
lp->next = freetmpl;
freetmpl = lp;
#ifdef ALLOC_DEBUG
printf ("stack holder %d on tmp holder list\n", lp);
#endif
lp = np;
}
tmpl = (struct tmplist *) 0;
}
char *tmpstr (char *s)
{
char *ret;
size_t l;
ret = (char *) tmpalloc (l = (strlen (s) + 1));
if (ret != (char *) 0)
bcopy (s, ret, l);
else
fatal ("cannot allocate string space!\n", (char *) 0);
return (ret);
}