2013-10-28 13:28:42 +08:00
|
|
|
//-----------------------------------------------------------------------------
|
2015-03-17 23:09:59 +08:00
|
|
|
// Utility functions used by the Unix port. Notably, our memory allocation;
|
2013-10-28 13:28:42 +08:00
|
|
|
// 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>
|
|
|
|
//-----------------------------------------------------------------------------
|
2015-03-29 08:33:46 +08:00
|
|
|
#include <config.h>
|
2013-10-28 13:28:42 +08:00
|
|
|
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <stdio.h>
|
2015-03-19 01:02:11 +08:00
|
|
|
#include <time.h>
|
2013-10-28 13:28:42 +08:00
|
|
|
|
|
|
|
#include "solvespace.h"
|
|
|
|
|
2015-03-24 01:49:04 +08:00
|
|
|
namespace SolveSpace {
|
|
|
|
|
2013-10-28 13:28:42 +08:00
|
|
|
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);
|
2015-03-18 01:02:04 +08:00
|
|
|
fputc('\n', stderr);
|
2013-10-28 13:28:42 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void GetAbsoluteFilename(char *file)
|
|
|
|
{
|
2015-03-17 23:09:59 +08:00
|
|
|
char expanded[MAX_PATH];
|
|
|
|
realpath(file, expanded);
|
|
|
|
strcpy(file, expanded);
|
2013-10-28 13:28:42 +08:00
|
|
|
}
|
|
|
|
|
2015-03-19 01:02:11 +08:00
|
|
|
int64_t GetUnixTime(void)
|
|
|
|
{
|
|
|
|
time_t ret;
|
|
|
|
time(&ret);
|
|
|
|
return (int64_t)ret;
|
|
|
|
}
|
|
|
|
|
2013-10-28 13:28:42 +08:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// 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;
|
2014-04-08 09:51:55 +08:00
|
|
|
memset(&h[1], 0, n);
|
2013-10-28 13:28:42 +08:00
|
|
|
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);
|
|
|
|
}
|
2013-11-18 15:31:23 +08:00
|
|
|
|
|
|
|
void InitHeaps(void) {
|
|
|
|
/* nothing to do */
|
|
|
|
}
|
2015-03-24 01:49:04 +08:00
|
|
|
|
|
|
|
};
|