1 /*
2 block.c
3
4 allows multiple arrays to be malloc'ed in one easy step
5
6 Simon Kilvington, University of Southampton, 1995
7 */
8
9 #include "bbltyp.h"
10 #include <stdarg.h>
11
12 /* the routine that does all the work */
13 static int block__doalloc(int, block_ptr *, const char *, va_list);
14
15 /*
16 block_alloc
17 allocates a block of memory for a set of arrays
18 the types string determines what the arrays are arrays of, one char per array, types are:
19 c - char
20 i - int
21 f - float
22 d - double
23 B - int
24 v - void *
25 eg int *intarray;
26 float *floatarray1, *floatarray2;
27 block_alloc(&handle, "iff", &intarray, nentries1, &floatarray1, nentries2, &floatarray2, nentries3);
28 ...code...
29 block_free(&handle);
30 returns TRUE if all went well
31 */
32
33 int
block_alloc(block_ptr * handle,const char * types,...)34 block_alloc(block_ptr *handle, const char *types, ...)
35 {
36 int okay;
37 va_list ap;
38
39 va_start(ap, types);
40 okay = block__doalloc(FALSE, handle, types, ap);
41 va_end(ap);
42
43 return okay;
44 }
45
46 /*
47 block_calloc
48 as block_alloc, but all the space is initialised to 0
49 */
50
51 int
block_calloc(block_ptr * handle,const char * types,...)52 block_calloc(block_ptr *handle, const char *types, ...)
53 {
54 int okay;
55 va_list ap;
56
57 va_start(ap, types);
58 okay = block__doalloc(TRUE, handle, types, ap);
59 va_end(ap);
60
61 return okay;
62 }
63
64 /*
65 block_free
66 deallocates space claimed with block_[c]alloc
67 */
68
69 void
block_free(block_ptr * handle)70 block_free(block_ptr *handle)
71 {
72 free(*handle);
73 *handle = NULL;
74
75 return;
76 }
77
78 /*
79 block__doalloc
80 does all the work for both the above alloc'ing routines
81 */
82
83 #define typesize(CHAR, TYPE) if(types[i] == CHAR) { \
84 (void) va_arg(ap, TYPE **); \
85 size += va_arg(ap, int) * sizeof(TYPE); \
86 continue; }
87
88 #define typeptr(CHAR, TYPE) if(types[i] == CHAR) { \
89 array = (void *) va_arg(ap, TYPE **); \
90 *((TYPE **) array) = (TYPE *) ((long) (*handle) + ptr); \
91 ptr += va_arg(ap, int) * sizeof(TYPE); \
92 continue; }
93
94 static int
block__doalloc(int clear,block_ptr * handle,const char * types,va_list initap)95 block__doalloc(int clear, block_ptr *handle, const char *types, va_list initap)
96 {
97 va_list ap;
98 int i, size;
99 long ptr;
100 void *array;
101
102 /* calc how much space we are gonna need */
103 va_copy(ap, initap);
104 size = 0;
105 for(i=0; types[i] != '\0'; i++)
106 {
107 typesize('c', char);
108 typesize('i', int);
109 typesize('f', float);
110 typesize('d', double);
111 typesize('B', int);
112 typesize('v', void *);
113 }
114
115 *handle = (block_ptr) ((clear) ? calloc(size, 1) : malloc(size));
116
117 /* set up the ptrs if we can alloc the memory */
118 if(*handle != NULL)
119 {
120 va_copy(ap, initap);
121 ptr = 0;
122 for(i=0; types[i] != '\0'; i++)
123 {
124 typeptr('c', char);
125 typeptr('i', int);
126 typeptr('f', float);
127 typeptr('d', double);
128 typeptr('B', int);
129 typeptr('v', void *);
130 }
131 }
132
133 return (*handle != NULL);
134 }
135
136