The R Project SVN R

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4394 ripley 1
/*
2
 * GraphApp - Cross-Platform Graphics Programming Library.
3
 *
4
 * File: array.c -- memory allocation functions.
5
 * Platform: Neutral  Version: 2.35  Date: 1998/03/04
6
 *
7
 * Version: 2.30  Changes: Original version by Lachlan Patrick.
8
 * Version: 2.35  Changes: Join and append improved by Jim McDonald.
9
 */
10
 
11
/* Copyright (C) 1993-1998 Lachlan Patrick
12
 
13
   This file is part of GraphApp, a cross-platform C graphics library.
14
 
15
   GraphApp is free software; you can redistribute it and/or modify it
16
   under the terms of the GNU Library General Public License.
17
   GraphApp is distributed in the hope that it will be useful, but
18
   WITHOUT ANY WARRANTY.
19
 
20
   See the file COPYLIB.TXT for details.
21
*/
22
 
9184 ripley 23
/* Changes for R: use winmalloc etc not malloc (which does not free) */
24
 
4394 ripley 25
#include <stdlib.h>
26
#include "internal.h"
27
 
28
#ifndef array
29
 
30
#define create(type)  ( (type*) memalloc(sizeof(type)) )
31
#define array(n,type) ( (type*) memalloc(n*sizeof(type)) )
32
#define len(a)        ( memlength((char*)(a))/sizeof((a)[0]) )
33
#define element(a,i)  ( (((i)<len(a)) && ((i)>=0)) ? (a)[i] : 0 )
34
#define append(a,e)   ( *(char**)&(a)=memexpand((char*)(a),sizeof((a)[0])), \
35
				(a)[len(a)-1]=(e) )
36
#define shrink(a,ns)  ( *(char**)&(a)=memrealloc((char*)(a),(ns)) )
37
#define join(a,b)     ( *(char**)&(a)=memjoin((char*)(a),(char*)(b)) )
38
#define discard(a)    ( memfree((char*)(a)), (a)=0 )
39
 
40
char *	memalloc(long size);
41
char *	memrealloc(char *a, long new_size);
42
void	memfree(char *a);
43
long	memlength(char *a);
44
char *	memexpand(char *a, long extra);
45
char *	memjoin(char *a, char *b);
46
 
47
#endif /* array defintions */
48
 
49
#define TRACEAR(a)
50
 
51
char * memalloc(long size)
52
{
53
	long *block;
54
	char *a;
55
	long i, datasize;
56
        TRACEAR("alloc");
57
	datasize = (((size + 4) >> 2) << 2);
58
	#ifdef COMPILER
59
	  #if (COMPILER <= 16)
60
		if ((sizeof(long)+datasize) >= (1<<16))
61
			return NULL;
62
	  #endif
63
	#endif
64
	block = (long *) winmalloc(sizeof(long) + datasize);
65
	if (block == NULL)
66
		return NULL;
67
	block[0] = size;
68
	a = (char *) & block[1];
69
	for (i=0; i<datasize; i++)
70
		a[i] = '\0';
71
	return a;
72
}
73
 
74
char * memrealloc(char *a, long new_size)
75
{
76
	long *block;
77
	long i, size, oldsize, newsize;
78
        TRACEAR("realloc");
79
	if (new_size <= 0) {
80
		memfree(a);
81
		return NULL;
82
	}
83
 
84
	if (a == NULL) {
85
		block = NULL;
86
		size = 0;
87
	}
88
	else {
89
		block = ((long*)a) - 1;
90
		size = block[0];
91
	}
92
 
93
	oldsize = size ? (((size + 4) >> 2) << 2) : 0;
94
	newsize = (((new_size + 4) >> 2) << 2);
95
 
96
	if ( newsize != oldsize ) {
97
		#ifdef COMPILER
98
		  #if (COMPILER <= 16)
99
			if ((sizeof(long)+newsize) >= (1<<16))
100
				return NULL;
101
		  #endif
102
		#endif
103
		block = (long *) winrealloc(block, sizeof(long) + newsize);
104
		if (block == NULL)
105
			return NULL;
106
		a = (char *) & block[1];
107
		for (i=oldsize; i<newsize; i++)
108
			a[i] = '\0';
109
	}
110
 
111
	block[0] = new_size;
112
	return a;
113
}
114
 
115
long memlength(char *a)
116
{
117
	return (a) ? ((long*)(a)-1)[0] : 0;
118
}
119
 
120
void memfree(char *a)
121
{
122
	if (a) winfree((long*)(a)-1);
123
}
124
 
125
char * memexpand(char *a, long extra)
126
{
127
	long *block;
128
	long i, size, oldsize, newsize;
129
        TRACEAR("exp");
130
	if (extra == 0)
131
		return a;
132
 
133
	if (a == NULL) {
134
		block = NULL;
135
		size = 0;
136
	}
137
	else {
138
		block = ((long*)a) - 1;
139
		size = block[0];
140
	}
141
 
142
	oldsize = size ? (((size + 4) >> 2) << 2) : 0;
143
	newsize = (((size + extra + 4) >> 2) << 2);
144
 
145
	if ( newsize != oldsize ) {
146
		#ifdef COMPILER
147
		  #if (COMPILER <= 16)
148
			if ((sizeof(long)+newsize) >= (1<<16))
149
				return NULL;
150
		  #endif
151
		#endif
152
		block = (long *) winrealloc(block, sizeof(long) + newsize);
153
		if (block == NULL)
154
			return NULL;
155
		a = (char *) & block[1];
156
		for (i=oldsize; i<newsize; i++)
157
			a[i] = '\0';
158
	}
159
 
160
	block[0] = size + extra;
161
	return a;
162
}
163
 
164
char * memjoin(char *a, char *b)
165
{
166
	long i, size, extra;
167
 
168
	size = memlength(a);
169
	extra = memlength(b);
170
	a = memexpand(a, extra);
171
	if (a) {
172
		for (i=0; i<extra; i++)
173
			a[i+size] = b[i];
174
	}
175
	return a;
176
}
177
 
178
 
179