blob: 21c8d718156d7f4513a8f2ac1fafcf8e83dd1e41 [file] [log] [blame]
/*
* GraphApp - Cross-Platform Graphics Programming Library.
*
* File: array.c -- memory allocation functions.
* Platform: Neutral Version: 2.35 Date: 1998/03/04
*
* Version: 2.30 Changes: Original version by Lachlan Patrick.
* Version: 2.35 Changes: Join and append improved by Jim McDonald.
*/
/* Copyright (C) 1993-1998 Lachlan Patrick
This file is part of GraphApp, a cross-platform C graphics library.
GraphApp is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License.
GraphApp is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY.
See the file COPYLIB.TXT for details.
*/
#include <stdlib.h>
#include "internal.h"
#ifndef array
#define create(type) ( (type*) memalloc(sizeof(type)) )
#define array(n,type) ( (type*) memalloc(n*sizeof(type)) )
#define len(a) ( memlength((char*)(a))/sizeof((a)[0]) )
#define element(a,i) ( (((i)<len(a)) && ((i)>=0)) ? (a)[i] : 0 )
#define append(a,e) ( *(char**)&(a)=memexpand((char*)(a),sizeof((a)[0])), \
(a)[len(a)-1]=(e) )
#define shrink(a,ns) ( *(char**)&(a)=memrealloc((char*)(a),(ns)) )
#define join(a,b) ( *(char**)&(a)=memjoin((char*)(a),(char*)(b)) )
#define discard(a) ( memfree((char*)(a)), (a)=0 )
char * memalloc(long size);
char * memrealloc(char *a, long new_size);
void memfree(char *a);
long memlength(char *a);
char * memexpand(char *a, long extra);
char * memjoin(char *a, char *b);
#endif /* array defintions */
#define TRACEAR(a)
char * memalloc(long size)
{
long *block;
char *a;
long i, datasize;
TRACEAR("alloc");
datasize = (((size + 4) >> 2) << 2);
#ifdef COMPILER
#if (COMPILER <= 16)
if ((sizeof(long)+datasize) >= (1<<16))
return NULL;
#endif
#endif
block = (long *) malloc(sizeof(long) + datasize);
if (block == NULL)
return NULL;
block[0] = size;
a = (char *) & block[1];
for (i=0; i<datasize; i++)
a[i] = '\0';
return a;
}
char * memrealloc(char *a, long new_size)
{
long *block;
long i, size, oldsize, newsize;
TRACEAR("realloc");
if (new_size <= 0) {
memfree(a);
return NULL;
}
if (a == NULL) {
block = NULL;
size = 0;
}
else {
block = ((long*)a) - 1;
size = block[0];
}
oldsize = size ? (((size + 4) >> 2) << 2) : 0;
newsize = (((new_size + 4) >> 2) << 2);
if ( newsize != oldsize ) {
#ifdef COMPILER
#if (COMPILER <= 16)
if ((sizeof(long)+newsize) >= (1<<16))
return NULL;
#endif
#endif
block = (long *) realloc(block, sizeof(long) + newsize);
if (block == NULL)
return NULL;
a = (char *) & block[1];
for (i=oldsize; i<newsize; i++)
a[i] = '\0';
}
block[0] = new_size;
return a;
}
long memlength(char *a)
{
return (a) ? ((long*)(a)-1)[0] : 0;
}
void memfree(char *a)
{
if (a) free((long*)(a)-1);
}
char * memexpand(char *a, long extra)
{
long *block;
long i, size, oldsize, newsize;
TRACEAR("exp");
if (extra == 0)
return a;
if (a == NULL) {
block = NULL;
size = 0;
}
else {
block = ((long*)a) - 1;
size = block[0];
}
oldsize = size ? (((size + 4) >> 2) << 2) : 0;
newsize = (((size + extra + 4) >> 2) << 2);
if ( newsize != oldsize ) {
#ifdef COMPILER
#if (COMPILER <= 16)
if ((sizeof(long)+newsize) >= (1<<16))
return NULL;
#endif
#endif
block = (long *) realloc(block, sizeof(long) + newsize);
if (block == NULL)
return NULL;
a = (char *) & block[1];
for (i=oldsize; i<newsize; i++)
a[i] = '\0';
}
block[0] = size + extra;
return a;
}
char * memjoin(char *a, char *b)
{
long i, size, extra;
size = memlength(a);
extra = memlength(b);
a = memexpand(a, extra);
if (a) {
for (i=0; i<extra; i++)
a[i+size] = b[i];
}
return a;
}