solvespace/fltk/fltkutil.cpp

108 lines
2.5 KiB
C++

//-----------------------------------------------------------------------------
// Utility functions used by the FLTK port. Notably, our memory allocation;
// we use two separate allocators, one for long-lived stuff and one for
// stuff that gets freed after every regeneration of the model, to save us
// the trouble of freeing the latter explicitly.
//
// Copyright 2008-2013 Jonathan Westhues.
// Copyright 2013 Daniel Richard G. <skunk@iSKUNK.ORG>
//-----------------------------------------------------------------------------
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <FL/filename.H>
#include "solvespace.h"
void dbp(const char *str, ...)
{
va_list f;
static char buf[1024*50];
va_start(f, str);
vsnprintf(buf, sizeof(buf), str, f);
va_end(f);
fputs(buf, stderr);
}
void GetAbsoluteFilename(char *file)
{
char absoluteFile[PATH_MAX];
fl_filename_absolute(absoluteFile, sizeof(absoluteFile), file);
strcpy(file, absoluteFile);
}
//-----------------------------------------------------------------------------
// A separate heap, on which we allocate expressions. Maybe a bit faster,
// since fragmentation is less of a concern, and it also makes it possible
// to be sloppy with our memory management, and just free everything at once
// at the end.
//-----------------------------------------------------------------------------
typedef struct _AllocTempHeader AllocTempHeader;
typedef struct _AllocTempHeader {
AllocTempHeader *prev;
AllocTempHeader *next;
} AllocTempHeader;
static AllocTempHeader *Head = NULL;
void *AllocTemporary(size_t n)
{
AllocTempHeader *h =
(AllocTempHeader *)malloc(n + sizeof(AllocTempHeader));
h->prev = NULL;
h->next = Head;
Head = h;
return (void *)&h[1];
}
void FreeTemporary(void *p)
{
AllocTempHeader *h = (AllocTempHeader *)p - 1;
if(h->prev) {
h->prev->next = h->next;
} else {
Head = h->next;
}
if(h->next) h->next->prev = h->prev;
free(h);
}
void FreeAllTemporary(void)
{
AllocTempHeader *h = Head;
while(h) {
AllocTempHeader *f = h;
h = h->next;
free(f);
}
Head = NULL;
}
void *MemRealloc(void *p, size_t n) {
if(!p) {
return MemAlloc(n);
}
p = realloc(p, n);
if(!p) oops();
return p;
}
void *MemAlloc(size_t n) {
void *p = malloc(n);
if(!p) oops();
return p;
}
void MemFree(void *p) {
free(p);
}