2002-11-01 18:22:40 +00:00
|
|
|
/*
|
|
|
|
* malloc.c: safe wrappers around malloc, realloc, free, strdup
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdarg.h>
|
2003-11-03 09:10:19 +00:00
|
|
|
#include <string.h>
|
2002-11-01 18:22:40 +00:00
|
|
|
#include "halibut.h"
|
|
|
|
|
|
|
|
#ifdef LOGALLOC
|
|
|
|
#define LOGPARAMS char *file, int line,
|
|
|
|
static FILE *logallocfp = NULL;
|
2003-04-04 14:43:36 +00:00
|
|
|
static int logline = 2; /* off by 1: `null pointer is' */
|
2002-11-01 21:52:36 +00:00
|
|
|
static void loginc(void)
|
2002-11-01 18:22:40 +00:00
|
|
|
{
|
|
|
|
}
|
2002-11-01 21:52:36 +00:00
|
|
|
static void logallocinit(void)
|
2002-11-01 18:22:40 +00:00
|
|
|
{
|
2003-04-04 14:43:36 +00:00
|
|
|
if (!logallocfp)
|
|
|
|
{
|
|
|
|
logallocfp = fopen("malloc.log", "w");
|
|
|
|
if (!logallocfp)
|
|
|
|
{
|
|
|
|
fprintf(stderr, "panic: unable to open malloc.log\n");
|
|
|
|
exit(10);
|
2002-11-01 18:22:40 +00:00
|
|
|
}
|
2003-04-04 14:43:36 +00:00
|
|
|
setvbuf(logallocfp, NULL, _IOLBF, BUFSIZ);
|
|
|
|
fprintf(logallocfp, "null pointer is %p\n", NULL);
|
|
|
|
}
|
2002-11-01 18:22:40 +00:00
|
|
|
}
|
2002-11-01 21:52:36 +00:00
|
|
|
static void logprintf(char *fmt, ...)
|
2002-11-01 18:22:40 +00:00
|
|
|
{
|
2003-04-04 14:43:36 +00:00
|
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
|
|
vfprintf(logallocfp, fmt, ap);
|
|
|
|
va_end(ap);
|
2002-11-01 18:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define LOGPRINT(x) ( logallocinit(), logprintf x )
|
|
|
|
#define LOGINC do { loginc(); logline++; } while (0)
|
|
|
|
#else
|
|
|
|
#define LOGPARAMS
|
|
|
|
#define LOGPRINT(x)
|
|
|
|
#define LOGINC ((void)0)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*
|
|
|
|
* smalloc should guarantee to return a useful pointer - Halibut
|
|
|
|
* can do nothing except die when it's out of memory anyway.
|
|
|
|
*/
|
2002-11-01 21:52:36 +00:00
|
|
|
void *(smalloc) (LOGPARAMS int size) {
|
2003-04-04 14:43:36 +00:00
|
|
|
void *p;
|
|
|
|
LOGINC;
|
|
|
|
LOGPRINT(("%s %d malloc(%ld)", file, line, (long) size));
|
|
|
|
p = malloc(size);
|
|
|
|
if (!p)
|
|
|
|
fatal(err_nomemory);
|
|
|
|
LOGPRINT((" returns %p\n", p));
|
|
|
|
return p;
|
2002-11-01 18:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* sfree should guaranteeably deal gracefully with freeing NULL
|
|
|
|
*/
|
2002-11-01 21:52:36 +00:00
|
|
|
void (sfree) (LOGPARAMS void *p) {
|
2003-04-04 14:43:36 +00:00
|
|
|
if (p)
|
|
|
|
{
|
|
|
|
LOGINC;
|
|
|
|
LOGPRINT(("%s %d free(%p)\n", file, line, p));
|
|
|
|
free(p);
|
|
|
|
}
|
2002-11-01 18:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* srealloc should guaranteeably be able to realloc NULL
|
|
|
|
*/
|
2002-11-01 21:52:36 +00:00
|
|
|
void *(srealloc) (LOGPARAMS void *p, int size) {
|
2003-04-04 14:43:36 +00:00
|
|
|
void *q;
|
|
|
|
if (p)
|
|
|
|
{
|
|
|
|
LOGINC;
|
|
|
|
LOGPRINT(("%s %d realloc(%p,%ld)", file, line, p, (long) size));
|
|
|
|
q = realloc(p, size);
|
|
|
|
LOGPRINT((" returns %p\n", q));
|
|
|
|
} else
|
|
|
|
{
|
|
|
|
LOGINC;
|
|
|
|
LOGPRINT(("%s %d malloc(%ld)", file, line, (long) size));
|
|
|
|
q = malloc(size);
|
|
|
|
LOGPRINT((" returns %p\n", q));
|
|
|
|
}
|
|
|
|
if (!q)
|
|
|
|
fatal(err_nomemory);
|
|
|
|
return q;
|
2002-11-01 18:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* dupstr is like strdup, but with the never-return-NULL property
|
|
|
|
* of smalloc (and also reliably defined in all environments :-)
|
|
|
|
*/
|
2002-11-01 21:52:36 +00:00
|
|
|
char *dupstr(char *s)
|
2002-11-01 18:22:40 +00:00
|
|
|
{
|
2003-04-04 14:43:36 +00:00
|
|
|
char *r = smalloc(1 + strlen(s));
|
|
|
|
strcpy(r, s);
|
|
|
|
return r;
|
2002-11-01 18:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Duplicate a linked list of words
|
|
|
|
*/
|
2002-11-01 21:52:36 +00:00
|
|
|
word *dup_word_list(word * w)
|
2002-11-01 18:22:40 +00:00
|
|
|
{
|
2003-04-04 14:43:36 +00:00
|
|
|
word *head, **eptr = &head;
|
2002-11-01 18:22:40 +00:00
|
|
|
|
2003-04-04 14:43:36 +00:00
|
|
|
while (w)
|
|
|
|
{
|
|
|
|
word *newwd = mknew(word);
|
|
|
|
*newwd = *w; /* structure copy */
|
|
|
|
newwd->text = ustrdup(w->text);
|
|
|
|
if (w->alt)
|
|
|
|
newwd->alt = dup_word_list(w->alt);
|
|
|
|
*eptr = newwd;
|
|
|
|
newwd->next = NULL;
|
|
|
|
eptr = &newwd->next;
|
2002-11-01 18:22:40 +00:00
|
|
|
|
2003-04-04 14:43:36 +00:00
|
|
|
w = w->next;
|
|
|
|
}
|
2002-11-01 18:22:40 +00:00
|
|
|
|
2003-04-04 14:43:36 +00:00
|
|
|
return head;
|
2002-11-01 18:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Free a linked list of words
|
|
|
|
*/
|
2002-11-01 21:52:36 +00:00
|
|
|
void free_word_list(word * w)
|
2002-11-01 18:22:40 +00:00
|
|
|
{
|
2003-04-04 14:43:36 +00:00
|
|
|
word *t;
|
|
|
|
while (w)
|
|
|
|
{
|
|
|
|
t = w;
|
|
|
|
w = w->next;
|
|
|
|
sfree(t->text);
|
|
|
|
if (t->alt)
|
|
|
|
free_word_list(t->alt);
|
|
|
|
sfree(t);
|
|
|
|
}
|
2002-11-01 18:22:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Free a linked list of paragraphs
|
|
|
|
*/
|
2002-11-01 21:52:36 +00:00
|
|
|
void free_para_list(paragraph * p)
|
2002-11-01 18:22:40 +00:00
|
|
|
{
|
2003-04-04 14:43:36 +00:00
|
|
|
paragraph *t;
|
|
|
|
while (p)
|
|
|
|
{
|
|
|
|
t = p;
|
|
|
|
p = p->next;
|
|
|
|
sfree(t->keyword);
|
|
|
|
free_word_list(t->words);
|
|
|
|
sfree(t);
|
|
|
|
}
|
2002-11-01 18:22:40 +00:00
|
|
|
}
|