1:
2: // Copyright (c) 1999-2010 by Digital Mars
3: // All Rights Reserved
4: // written by Walter Bright
5: // http://www.digitalmars.com
6: // License for redistribution is by either the Artistic License
7: // in artistic.txt, or the GNU General Public License in gnu.txt.
8: // See the included readme.txt for details.
9:
10: #include <stdio.h>
11: #include <stdlib.h>
12: #include <stdarg.h>
13: #include <string.h>
14: static char __file__[] = __FILE__; /* for tassert.h */
15: #include "tassert.h"
16:
17: #if (defined (__SVR4) && defined (__sun))
18: #include <alloca.h>
19: #endif
20:
21: #if _MSC_VER || __MINGW32__
22: #include <malloc.h>
23: #endif
24:
25: #if IN_GCC
26: #include "gdc_alloca.h"
27: #endif
28:
29: #if _WIN32
30: #include <windows.h>
31: #endif
32:
33: #ifndef _WIN32
34: #include <sys/types.h>
35: #include <sys/stat.h>
36: #include <fcntl.h>
37: #include <errno.h>
38: #include <unistd.h>
39: #include <utime.h>
40: #endif
41:
42: #include "port.h"
43: #include "root.h"
44: #include "dchar.h"
45: #include "rmem.h"
46:
47:
48: /********************************* Array ****************************/
49:
50: Array::Array()
51: {
52: data = SMALLARRAYCAP ? &smallarray[0] : NULL;
53: dim = 0;
54: allocdim = SMALLARRAYCAP;
55: }
56:
57: Array::~Array()
58: {
59: if (data != &smallarray[0])
60: mem.free(data);
61: }
62:
63: void Array::mark()
64: { unsigned u;
65:
66: mem.mark(data);
67: for (u = 0; u < dim; u++)
68: mem.mark(data[u]); // BUG: what if arrays of Object's?
69: }
70:
71: void Array::reserve(unsigned nentries)
72: {
73: //printf("Array::reserve: dim = %d, allocdim = %d, nentries = %d\n", dim, allocdim, nentries);
74: if (allocdim - dim < nentries)
75: {
76: if (allocdim == 0)
77: { // Not properly initialized, someone memset it to zero
78: if (nentries <= SMALLARRAYCAP)
79: { allocdim = SMALLARRAYCAP;
80: data = SMALLARRAYCAP ? &smallarray[0] : NULL;
81: }
82: else
83: { allocdim = nentries;
84: data = (void **)mem.malloc(allocdim * sizeof(*data));
85: }
86: }
87: else if (allocdim == SMALLARRAYCAP)
88: {
89: allocdim = dim + nentries;
90: data = (void **)mem.malloc(allocdim * sizeof(*data));
91: memcpy(data, &smallarray[0], dim * sizeof(*data));
92: }
93: else
94: { allocdim = dim + nentries;
95: data = (void **)mem.realloc(data, allocdim * sizeof(*data));
96: }
97: }
98: }
99:
100: void Array::setDim(unsigned newdim)
101: {
102: if (dim < newdim)
103: {
104: reserve(newdim - dim);
105: }
106: dim = newdim;
107: }
108:
109: void Array::fixDim()
110: {
111: if (dim != allocdim)
112: {
113: if (allocdim >= SMALLARRAYCAP)
114: {
115: if (dim <= SMALLARRAYCAP)
116: {
117: memcpy(&smallarray[0], data, dim * sizeof(*data));
118: mem.free(data);
119: }
120: else
121: data = (void **)mem.realloc(data, dim * sizeof(*data));
122: }
123: allocdim = dim;
124: }
125: }
126:
127: void Array::push(void *ptr)
128: {
129: reserve(1);
130: data[dim++] = ptr;
131: }
132:
133: void *Array::pop()
134: {
135: return data[--dim];
136: }
137:
138: void Array::shift(void *ptr)
139: {
140: reserve(1);
141: memmove(data + 1, data, dim * sizeof(*data));
142: data[0] = ptr;
143: dim++;
144: }
145:
146: void Array::insert(unsigned index, void *ptr)
147: {
148: reserve(1);
149: memmove(data + index + 1, data + index, (dim - index) * sizeof(*data));
150: data[index] = ptr;
151: dim++;
152: }
153:
154:
155: void Array::insert(unsigned index, Array *a)
156: {
157: if (a)
158: { unsigned d;
159:
160: d = a->dim;
161: reserve(d);
162: if (dim != index)
163: memmove(data + index + d, data + index, (dim - index) * sizeof(*data));
164: memcpy(data + index, a->data, d * sizeof(*data));
165: dim += d;
166: }
167: }
168:
169:
170: /***********************************
171: * Append array a to this array.
172: */
173:
174: void Array::append(Array *a)
175: {
176: insert(dim, a);
177: }
178:
179: void Array::remove(unsigned i)
180: {
181: if (dim - i - 1)
182: memmove(data + i, data + i + 1, (dim - i - 1) * sizeof(data[0]));
183: dim--;
184: }
185:
186: char *Array::toChars()
187: {
188: unsigned len;
189: unsigned u;
190: char **buf;
191: char *str;
192: char *p;
193:
194: buf = (char **)alloca(dim * sizeof(char *));
warning C6255: _alloca indicates failure by raising a stack overflow exception. Consider using _malloca instead
195: len = 2;
196: for (u = 0; u < dim; u++)
197: {
198: buf[u] = ((Object *)data[u])->toChars();
199: len += strlen(buf[u]) + 1;
200: }
201: str = (char *)mem.malloc(len);
202:
203: str[0] = '[';
204: p = str + 1;
205: for (u = 0; u < dim; u++)
206: {
207: if (u)
208: *p++ = ',';
209: len = strlen(buf[u]);
210: memcpy(p,buf[u],len);
211: p += len;
212: }
213: *p++ = ']';
214: *p = 0;
215: return str;
216: }
217:
218: void Array::zero()
219: {
220: memset(data,0,dim * sizeof(data[0]));
221: }
222:
223: void *Array::tos()
224: {
225: return dim ? data[dim - 1] : NULL;
226: }
227:
228: int
229: #if _WIN32
230: __cdecl
231: #endif
232: Array_sort_compare(const void *x, const void *y)
233: {
234: Object *ox = *(Object **)x;
235: Object *oy = *(Object **)y;
236:
237: return ox->compare(oy);
238: }
239:
240: void Array::sort()
241: {
242: if (dim)
243: {
244: qsort(data, dim, sizeof(Object *), Array_sort_compare);
245: }
246: }
247:
248: Array *Array::copy()
249: {
250: Array *a = new Array();
251:
252: a->setDim(dim);
253: memcpy(a->data, data, dim * sizeof(void *));
254: return a;
255: }
256:
257: