The R Project SVN R

Rev

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