The R Project SVN R

Rev

Rev 42521 | Go to most recent revision | Details | Compare with Previous | 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
 
23
#include <stdlib.h>
24
#include "internal.h"
25
 
26
#ifndef array
27
 
28
#define create(type)  ( (type*) memalloc(sizeof(type)) )
29
#define array(n,type) ( (type*) memalloc(n*sizeof(type)) )
30
#define len(a)        ( memlength((char*)(a))/sizeof((a)[0]) )
31
#define element(a,i)  ( (((i)<len(a)) && ((i)>=0)) ? (a)[i] : 0 )
32
#define append(a,e)   ( *(char**)&(a)=memexpand((char*)(a),sizeof((a)[0])), \
33
				(a)[len(a)-1]=(e) )
34
#define shrink(a,ns)  ( *(char**)&(a)=memrealloc((char*)(a),(ns)) )
35
#define join(a,b)     ( *(char**)&(a)=memjoin((char*)(a),(char*)(b)) )
36
#define discard(a)    ( memfree((char*)(a)), (a)=0 )
37
 
38
char *	memalloc(long size);
39
char *	memrealloc(char *a, long new_size);
40
void	memfree(char *a);
41
long	memlength(char *a);
42
char *	memexpand(char *a, long extra);
43
char *	memjoin(char *a, char *b);
44
 
45
#endif /* array defintions */
46
 
47
#define TRACEAR(a)
48
 
49
char * memalloc(long size)
50
{
45017 ripley 51
    long *block;
52
    char *a;
53
    long i, datasize;
54
    TRACEAR("alloc");
55
    datasize = (((size + 4) >> 2) << 2);
56
#ifdef COMPILER
57
#if (COMPILER <= 16)
58
    if ((sizeof(long)+datasize) >= (1<<16))
59
	return NULL;
60
#endif
61
#endif
62
    block = (long *) malloc(sizeof(long) + datasize);
63
    if (block == NULL)
64
	return NULL;
65
    block[0] = size;
66
    a = (char *) & block[1];
67
    for (i=0; i<datasize; i++)
68
	a[i] = '\0';
69
    return a;
4394 ripley 70
}
71
 
72
char * memrealloc(char *a, long new_size)
73
{
45017 ripley 74
    long *block;
75
    long i, size, oldsize, newsize;
76
    TRACEAR("realloc");
77
    if (new_size <= 0) {
78
	memfree(a);
79
	return NULL;
80
    }
4394 ripley 81
 
45017 ripley 82
    if (a == NULL) {
83
	block = NULL;
84
	size = 0;
85
    }
86
    else {
87
	block = ((long*)a) - 1;
88
	size = block[0];
89
    }
4394 ripley 90
 
45017 ripley 91
    oldsize = size ? (((size + 4) >> 2) << 2) : 0;
92
    newsize = (((new_size + 4) >> 2) << 2);
4394 ripley 93
 
45017 ripley 94
    if ( newsize != oldsize ) {
95
#ifdef COMPILER
96
#if (COMPILER <= 16)
97
	if ((sizeof(long)+newsize) >= (1<<16))
98
	    return NULL;
99
#endif
100
#endif
101
	block = (long *) realloc(block, sizeof(long) + newsize);
102
	if (block == NULL)
103
	    return NULL;
104
	a = (char *) & block[1];
105
	for (i=oldsize; i<newsize; i++)
106
	    a[i] = '\0';
107
    }
4394 ripley 108
 
45017 ripley 109
    block[0] = new_size;
110
    return a;
4394 ripley 111
}
112
 
113
long memlength(char *a)
114
{
45017 ripley 115
    return (a) ? ((long*)(a)-1)[0] : 0;
4394 ripley 116
}
117
 
118
void memfree(char *a)
119
{
45017 ripley 120
    if (a) free((long*)(a)-1);
4394 ripley 121
}
122
 
123
char * memexpand(char *a, long extra)
124
{
45017 ripley 125
    long *block;
126
    long i, size, oldsize, newsize;
127
    TRACEAR("exp");
128
    if (extra == 0)
129
	return a;
4394 ripley 130
 
45017 ripley 131
    if (a == NULL) {
132
	block = NULL;
133
	size = 0;
134
    }
135
    else {
136
	block = ((long*)a) - 1;
137
	size = block[0];
138
    }
4394 ripley 139
 
45017 ripley 140
    oldsize = size ? (((size + 4) >> 2) << 2) : 0;
141
    newsize = (((size + extra + 4) >> 2) << 2);
4394 ripley 142
 
45017 ripley 143
    if ( newsize != oldsize ) {
144
#ifdef COMPILER
145
#if (COMPILER <= 16)
146
	if ((sizeof(long)+newsize) >= (1<<16))
147
	    return NULL;
148
#endif
149
#endif
150
	block = (long *) realloc(block, sizeof(long) + newsize);
151
	if (block == NULL)
152
	    return NULL;
153
	a = (char *) & block[1];
154
	for (i=oldsize; i<newsize; i++)
155
	    a[i] = '\0';
156
    }
4394 ripley 157
 
45017 ripley 158
    block[0] = size + extra;
159
    return a;
4394 ripley 160
}
161
 
162
char * memjoin(char *a, char *b)
163
{
45017 ripley 164
    long i, size, extra;
4394 ripley 165
 
45017 ripley 166
    size = memlength(a);
167
    extra = memlength(b);
168
    a = memexpand(a, extra);
169
    if (a) {
170
	for (i=0; i<extra; i++)
171
	    a[i+size] = b[i];
172
    }
173
    return a;
4394 ripley 174
}